Python Django: Get what input field the cursor is in? - python

I am relatively new to Django and don’t have a lot of experience with python.
So far I display some input fields this way, where I'm looping through a range and then making the equivalent amount of fields. But is there some way to know which field is active, like what field is the cursor in?
The reason for why I want to know what field is active is because I have created a list with a bunch of special symbols, like math symbols and Greek letters, which the user can click, I then want the active field to display the clicked symbol. hope it makes sense
I was made aware of something called focus but I don’t think I understand how to use it. If someone could explain it would be great
This is the "important" part of my .html file
{% with ''|center:number_of_variables as range %}
{% for i in range %}
<input type="text" name="know_variable_description{{ forloop.counter0}}" placeholder="Symbol" >
<input type="text" name="know_variable_symbol{{ forloop.counter0}}" placeholder="Name" >
{{ forloop.counter0}}
{% endfor %}
{% endwith %}

in the input field, you can use the onfocus event
<input type="text" onfocus="myFunction()" name="know_variable_description{{ forloop.counter0}}" placeholder="Symbol" >
The onfocus event will call the function myFunction whenever the input is focused(active), and you can put your other logic in the function myFunction in javascript.

Related

Python & Flask HTML - Making n number of textboxes based on variable

I have a flask webpage I am trying to create. When users register for an account, they declare the number of agricultural fields they have. This is saved in a MySQL database. From this, I need users to add information on another input page. This input page should have "n" number of textboxes based on the number of fields they have.
Is there anyway to create "n" number of textboxes in HTML? I can read in the number of fields from their account but cannot find a way to create a variable number of textboxes within HTML.
I do not need this to be dynamic (the user add or remove) this needs to be a FIXED amount of textboxes.
I'm going to assume that because of flask you are using jina2 as your rendering engine, let's call the number of fields that need to be created n, you can just use the loop structure
{% for i in range(n) %}
<input name="field-{{i}}" />
{% endfor %}
you can get more info at https://jinja.palletsprojects.com/en/3.0.x/templates/#for
if you need more complex forms, I would recommend using WTForms.
Found a solution, it is a little ugly but should work.
in your html:
<table>
{% for x in range(fields | int) %}
<tr>
<td>
<input type="text" value="{{ x }}">
</td>
</tr>
{% endfor %}
</table>
in python:
def irrigation_input():
...... non important stuff here.....
fields=account_info_irr[9]
int(float(fields))
return render_template('irrigationinput.html',fields=fields)

CBV: How To Make A Drop Down Database Query Using Django FormView

What I would like to do is have a dropdown list containing objects from a database. When the user selects an object, I would like the information displayed on the page.
What I have been able to do is have the values shown in the dropdown list, but I have not been able to display the way I'd like. I've been trying to do so a certain way to hopefully be able to better control the look of the form.
models.py
class Vehicle(models.Model):
make = models.CharField(max_length=20)
model = models.CharField(max_length=20)
def __str__(self):
return self.make + ' ' + self.model
class Package(models.Model):
make_model = models.ForeignKey(
Vehicle, on_delete=models.CASCADE
)
name = models.CharField(max_length=20)
price = models.IntegerField()
views.py
class VehicleCompareView(FormView):
template_name = "main/somehtml.html"
form_class = forms.CompareForm
forms.py
objectlist = forms.ModelChoiceField(queryset=models.Package.objects.all() \
.order_by('make_model__make'))
html file
<form method="GET">
<select class="form-control">
<option value="0" selected disabled>Select Vehicle 1</option>
{% for q in form.objectlist %}
<option value="{{q.name}}">{{ q.make_model__make }}</option>
{% endfor %}
</select>
</form>
<div>
<p>Selected Vehicle: {{q.make_model__make}} {{q.make_model__model}}<br>
Price: ${{q.price}}
</p>
</div>
So let's start with what I have found that somewhat works from messing with the code.
If I use {{form}}, I get the package list, but it only displays the package name of course. If I attempt to use .values() in the query set in forms.py, it returns what I want, but in a dictionary(so it'll literally show 'make': 'someMake', 'model':'someModel', 'package:'somepackage') in the user dropdown list.
When I attempt to do the select/option way that I prefer to, after the for loop doing {{ q }} returns the same list of packages, but if I try to format what I want to see {{ q.make_model__make }} {{ q.make_model__model }} {{q.name}}, nothing shows except a dropdown of blanks(though the correct number of blanks).
There may be a better way than what I'm trying, but from a lot of searching and looking around on here I found my way to using a FormView with a ModelChoiceField query set. At the end of the day, I want a dropdown list to show Make Model Name from the database. When the user makes a selection, I would like to display the attributes on the page. Obviously I haven't even gotten to the issue of the selection part yet. From what I understand I'll need to use Ajax to have everything populate on selection. But that's a problem for another time. For now I'd just like the dropdown to display the way I'd like. Preferably using the select/option method so I can have control over the look rather than just rendering a generic form.
I solved my issue. I started reading all posts on Django query forms I could find, including those that didn't relate to my issue, to better understand exactly how everything works. Someone mentioned that the select statement is built inside the ModelForm. I then realized I was trying to force two different things, and why what I was doing didn't really make sense. I played with the code some more and here is what I did to solve my issue of displaying in the manner I wanted.
forms.py
objectlist = forms.queryset = models.Vehicle.objects.all().order_by('make')
html
<form>
<select class="form-control">
<option value="" selected disabled>Select Vehcile 1</option>
{% for q in form.objectlist %}
{% for b in q.package_set.all %}
<option value="">
{{ q.make }} {{ q.model }} {{ b.name }}
</option>
{% endfor %}
{% endfor %}
</select>
</form>
Using the nested for loop was the only way I could get the attributes of a related model to display inside the same select dropdown. The model Package has a foreign key called 'make_model' that refers to the model Vehicle. I wasn't able to call 'make_model__make' to display related vehicle names with the package in the dropdown list.
I'll leave my mistake up for anyone else having a similar issue to see what not to do in this situation along with what worked for me in the end.

Flask-Bootstrap, flask-wtf, adding class to submit button

I'm using a flask-wtf submit button as follows:
{{ wtf.form_field(form.submit, button_map={'submit': 'primary'}) }}
I want to add a class to the submit button but I can not find anything about that,
I'm pretty new with this but this http://pythonhosted.org/Flask-Bootstrap/basic-usage.html#templates did not helped me a lot.
Anything to recommend?
It's super-easy, usually, so unless Flask-Bootstrap does something odd you can just tell it what you want the class to be:
{{ wtf.form_field(form.submit, class="something", button_map={'submit': 'primary'}) }}
Generally, anything you pass to the rendering function that isn't recognised will be added as a parameter to the html, so you can do things like:
{{ wtf.form_field(form.submit, cats="mew") }}
And your resulting html field would be something like <input cats="mew" id="name" name="name" type="text" value="">

django template conditional html

I'm not sure if the title is technically correct (sorry, I'm new to python+django)
I have a template page that displays whether an application is running or stopped depends on its status. For example:
If app is running I want to display:
<div class="lt">
<a class="play" title="App running">
<span class="text_play">Running</span>
</a>
</div>
<div class="rt">
<input type="submit" onclick="stop_app()" value="stop" class="stop">
</div>
If the application is not running then show this instead:
<div class="lt">
<input type="submit" onclick="star_app()" value="start" class="play">
</div>
<div class="rt">
<a class="stop" title="Application is not running">
<span class="test_stop">Not Running</span>
</a>
</div>
This is kind of stripped down simplified html but my point is how can I avoid repeating myself?
The template is passed a dictionary of applications that it iterates over to display all the applications and their status (running/stopped). So currently I'm iterating over the dict twice, one for "stopped" apps and one for the "running" apps.
Hope it's clear
Thanks in advance
EDIT: This is what I have tried so far:
{% if application.service.status|lower == "enabled" %}
<div>...display running HTML...</div>
{% else %}
<div>...display the non-runing HTML..</div>
{% endif %}
I just want to know if I'm doing the right thing (DRY?)
What you proposed is pretty DRY.
{% if application.service.status|lower == "enabled" %}
<div>...display running HTML...</div>
{% else %}
<div>...display the non-runing HTML..</div>
{% endif %
Keep in mind you'll rely on the return render(request... for determining the html Django needs construct.
Your proposed solution will choose one or the other. I.e. if your non-running HTML needs to switch to running HTML you won't have access to it without another render.
To be more clear and concise, django templates will construct the appropriate HTML leaving out the alternative options or "conditions".
If you learn a bit of jQuery for example you can have elements of the page switch the currently displayed html. Expanding this to ajax will allow you to get status updates from the server and vice versa.

Django dynamic page generation with templates

I want to generate a page using templates and content blocks. The homepage generates a bunch of checkboxes to generate a searchquery for some specific values.
<div id="searchbar">
{% for foo in bar %}
<input type="checkbox" name="foovar" value={{foo.name}}{%if foo.name in p %}checked=checked{%endif%}>{{foo.name}}<br>
{%endfor%}
<input type="submit" value="Submit">
</div>
<div id="searchresult">
{% block content %}
{% endblock %}
The value 'bar' is the parameter passed to the template containing all specific values:
return render_to_response('testlink/foobar.html',{'bar':strings_from_database})
Now, upon submitting the values, they are passed to my view, some magic happens, and the result is passed via
return render(request,'extend/extend.html',{'result':result,'p':queried_values})
result is the result, p contains the queried values (to keep the checkboxes checked after submitting).
{% extends "testlink/foobar.html" %}
{% block content %}
<b>results:</b> <br>
{% for result in result %}
{{result.someattribute}}<br>
{% endfor %}
{% endblock %}
Now, my problem: The checkboxes disappear, probably as the 'for foo in bar' loop is executed again. Is there a way to prevent that from happening, without to hardcode the checkboxes into my template? This would work (i did it with a few checkboxes, but doing this with too many searchvalues is no fun. Also i would like to avoid additional database hits and passing the parameters again.
I agree with the comments above, using forms is almost always a better idea. But in response to your problem, if you are not passing the bar variable to the template, the loop that parses the checkboxes will not be executed. You would need to add bar to the context for extend.html:
return render(request,'extend/extend.html',
{'result':result,'p':queried_values, 'bar':strings_from_database})
Are you not doing this just to prevent hitting the DB twice? Has it proven a very expensive query to run?
Apart from setting up caching, you can always pass ALL the checkboxes "names" along with the form. You can add hidden inputs, like so:
{% for foo in bar %}
<input type="checkbox" name="foovar" value="{{foo.name}}" {%if foo.name in p %}checked="checked"{%endif%}>{{foo.name}}<br>
<input type="hidden" name="foovar_all" value="{{foo.name}}" />
{%endfor%}
Then you need to collect the values with something like:
bar = request.POST.getlist('foovar_all')
But you would need to rethink your code so the bar variables hold just the names of those objects in both views, it looks like it is a list of objects currently. Again, is it really necessary to avoid that query?

Categories

Resources