Want to use form and styling option together - python

I'm shifting an application from cgi to web.py. I want to use the web.form. However I've noticed that it creates a table on its own. Is it possible to style the created table (width, height, etc...)??? If yes, how???

The table is the result of form rendering, so naturally it’s placed within a form element. In my case it looks like this in the login.html template:
<form name="main" method="post" class="login">
$if not form.valid:
<p class="wrong">Login incorrect.</p>
$:form.render()
</form>
In the browser, when rendered, the form looks like this:
<form name="main" method="post" class="login">
<table>
<tr><th><label for="login">login</label></th><td><input type="text" id="login" name="login"/></td></tr>
<tr><th><label for="password">password</label></th><td><input type="password" id="password" name="password"/></td></tr>
<tr><th><label for="Login"></label></th><td><button id="Login" name="Login">Login</button></td></tr>
</table>
</form>
So you can apply arbitrary styling, including positioning, to this table using the following CSS:
form.login table { /* your styling */ }

Related

How do I embed django forms into my css design?

I am creating a website and already finished the frontend. Now I want to handle a form submit post request using python. I am trying to do this using django, but I can't figure out how I would
attach CSS classes, onchange eventhandlers and IDs to the django forms
insert divs and other html elements in between the django input elements within a single form
This is my current frontend:
<form method="post" autocomplete="off">
<p class="sub-header">Or just leave Us a Message:</p>
<div>
<div id="contact-layout">
<div class="input-container">
<input type="text" name="name" placeholder="Name">
<div class="input-bar"></div>
</div>
<div class="input-container">
<input type="text" name="email" placeholder="Email">
<div class="input-bar"></div>
</div>
<div class="input-container">
<input type="text" name="subject" placeholder="Subject">
<div class="input-bar"></div>
</div>
</div>
<div class="input-container">
<textarea name="message" placeholder="Type your message here..." id="message-input"></textarea>
<div class="input-bar"></div>
</div>
</div>
<div>
<p class="sub-header" id="user-image-header">Attach some images:</p>
<div id="file-upload">
<span class="form-button">Choose Files</span>
<input id="upload" type="file" onchange="LoadImage(this)" name="image" accept="image/*" multiple>
</div>
</div>
<div class="delimiter"></div>
<input class="form-button" type="submit" id="contact-submit" value="Submit">
<p id="submit-thanks">Thanks for submitting!</p>
as you can see I have a few "normal" html text inputs, a text area and an input for multiple image files.
In django I linked my static css files and setup my html frontend as a django template.
My django form looks like this so far:
class ContactForm(forms.Form):
name = forms.CharField()
email = forms.CharField()
phone = forms.CharField(required=False)
subject = forms.CharField(required=False)
message = forms.CharField(widget=forms.Textarea)
When I insert it into my frontend, It obviously doesn't look that good, as I have no Idea how I would represent my rather complex form design using django.
Could you point out how you would do this or maybe link a few good guides on how to approach something like this?
Also if possible provide some code examples :)
FYI I am familiar with python but I have never used django before, so maybe I am missing something obvious as for me it seem kind of overwhelming in it's complexity as a framework.
A good starting point is to familiarize yourself with what a default Django form generates. Here, for example, I was finding out for myself about the CheckboxSelectMultiple widget:
>>> class ZForm( forms.Form):
... foo = forms.MultipleChoiceField( choices=(('A','AA'),('B','BB'), ('C','CC')), widget=forms.CheckboxSelectMultiple )
...
>>> z = ZForm()
>>> z.as_p()
'<p><label>Foo:</label> <ul id="id_foo">\n <li><label for="id_foo_0"><input type="checkbox" name="foo" value="A" id="id_foo_0" />\n AA</label>\n\n</li>\n <li><label for="id_foo_1"><input type="checkbox" name="foo" value="B" id="id_foo_1" />\n BB</label>\n\n</li>\n <li><label for="id_foo_2"><input type="checkbox" name="foo" value="C" id="id_foo_2" />\n CC</label>\n\n</li>\n</ul></p>'
>>>
If you want to style it with css, the css ids generated by Django make it fairly. straightforward to describe any elements with css locators.If you don't want the default Django layouts, you can generate the form field-by-field in your template, or you can learn about django-crispy-forms (especially, layout helpers) which I wholeheartedly recommend.
As for where to inject css into Django, there are various ways, but a common one is through a block called something like css in your base template. The view template will look something like
{% extends "base.html" %}
{% block content %}
<!-- code to render your form -->
...
{ %endblock content %}
{% block css %}
/* base.html provides the surrounding style tags */
/* block.super inherits the css common to all pages using base.html */
{{block.super}}
/* additional styling for the form rendered in block content */
#id_foo label {
/* styling for labels on the foo field only */
whatever;
}
{% endblock css %}
In passing my own base.html also always loads Jquery (unsurprisingly in a block called scripts so I can per-template-override or augment should I need to) and has a block onready_js that gets rendered in this context, which saves an awful lot of easily-mistyped boilerplate around what can be a trivial Jquery snippet
<script type="text/javascript"> $(document).ready( function() {
{% block onready_js %}{% endblock onready_js %}
});
</script>
and you just put any per-template Jquery you need to be executed when the view is invoked into that block.
You can develop frontend and backend seperately in django. You can create a form on frontend and style it and handle it on your backend as
def my_route_handler(request):
if request.method == 'POST':
form = MyForm(request.POST)
if form.is_valid():
# do your processing
# return
There is no need to embed the django form in frontend.

can you change the way get method makes links for django?

I'm using django for a website that has a searchbar setup with a simple form:
<form method="get" action="/browse">
<div class="input-group col-md-12">
<input type="text" name="searchquery" class="form-control input-lg" placeholder="Search" style="margin-right:1vw; border-radius: 5px;"/>
<span class="input-group-btn">
<button class="btn btn-primary btn-lg" type="submit">
{% fontawesome_icon 'search' color='white' %}
</button>
</span>
</div>
</form>
This creates url's like this:
http://127.0.0.1:8000/browse/?searchquery=<searchquery>
However I've setup my django url like this:
http://127.0.0.1:8000/browse/<searchquery>/
I would like to use the second url (as it just looks a lot better in my opinion).
Is there a way I can make my form do this?
This isn't a question about Django. The browser simply can't do this with an HTML form. The action attribute of the form is set when it is loaded.
You could possibly write some JavaScript to make it do this. But that would be the wrong thing to do. Queries like search should be part of the querystring, not the URL.

How to get form data from input as variable in Flask?

I'm working on a simple UI to start and stop games by ID. The basic HTML I have written is as follows (game_id is populated by JS):
<div align="center" class="top">
<div align="left" class="game-id-input">
Game ID: <input type="text" name="game_id" id="game_id">
</div>
<div align="right" class="buttons">
<form action="{{ url_for('start_game', game_id=game_id) }}" method="get">
<input type="submit" name="start" value="Start game" class="btn btn-success"></input>
</form>
<form action="{{ url_for('end_game', game_id=game_id) }}" method="get">
<input type="submit" name="end" value="End game" class="btn btn-danger"></input>
</form>
</div>
</div>
which looks like
I also have Flask route functions defined for each of the forms:
#app.route("/start_game/<game_id>")
def start_game(game_id):
# ...
#app.route("/end_game/<game_id>")
def end_game(game_id):
# ...
In my forms, how can I make game_id correspond to the game_id from #game_id?
Currently when I submit start and end games, I get a File Not Found error because it's just appending the literal <game_id> to the route.
I'm new to web development. This should be trivial, but I don't know what to search for. Sorry in advance for such a simple question.
You are trying to generate a url based on user input, but user input isn't available when Jinja is rendering the template on the server side, it's only available on the client side. So if you wanted to post to URLs with the game id as a URL parameter, you would have to build that URL on the client side with JavaScript.
For what you're trying to do, that's not really necessary. You can get the submitted value of a named input with request.form['name']. Buttons are just like any other input, so you can name them to find out what action was taken.
#app.route('/manage_game', methods=['POST'])
def manage_game():
start = request.form['action'] == 'Start'
game_id = request.form['game_id']
if start:
start_game(game_id)
else:
stop_game(game_id)
return redirect(url_for('index'))
<form method="POST" action="{{ url_for('manage_game') }}">
<input type="text" name="game_id"/>
<input type="submit" name="action" value="Start"/>
<input type="submit" name="action" value="Stop"/>
</form>
Even that's more verbose than you need. Given that you'd know if a game was already in progress, just toggle the current status instead of picking an action. It would never make sense to start a game that's already started, only stop it.
I cannot comment, but I would like to correct davidism's code.
I believe that you need action within your form element with a value which corresponds to the function within the server python code for this to work. Minor, but an important correction. So it would be like this:
In your server.py:
#app.route('/manage_game', methods=['POST'])
def manage_game():
start = request.form['action'] == 'Start'
game_id = request.form['game_id']
if start:
start_game(game_id)
else:
stop_game(game_id)
return redirect(url_for('index'))
In your HTML:
<form method="POST" action=/manage_game>
<input type="text" name="game_id"/>
<input type="submit" name="action" value="Start"/>
<input type="submit" name="action" value="Stop"/>
</form>

Uploading Images Django Python

html:
<label for="image">Image</label>
Select a file: <input type="file" name="img">
Python:
image = (request.FILES.get("img"))
When I print image it prints none. If I just use {{form}} in between the <form> </form> tags it does send the image across to the view. However, for some specific reason I do not want to use the {{form}} method.
Any ideas how I can approach this problem? Thanks in advance!
Make sure your <form> has enctype="multipart/form-data", so it should look something like:
<form method="post" action="{URL}" enctype="multipart/form-data">
<input ...>
</form>

Adding in hidden input types changes my css

My code looks like this:
<form name="deleteUser" action="/groupmanager" method="post"><div id="x"> {% csrf_token %}
<input type="hidden" name="username" value = "{{name}}"></input>
<input type="hidden" name="groupName" value = "{{group}}"></input>
<input type="submit" name="xButton" id="xButton" value="x"></div></form>
And the code works exactly the way I want it to but now that I've added it, the layout of the page has changed. Now the button has moved onto a new line instead of being on the same line as the things before it in the code.
My code used to look like this:
<div id="x"><input type="submit" name="xButton" id="xButton" value="x"></div>
I beleave the change is in IE only ? Try adding position:relative; float:left to the css of hidden inputs.

Categories