Select the default choice field in a select in symfony and html - html

Here, I have in my database an insurance table where I store the insurance (with their name and logo) to which doctors can be affiliated.Now the doctor has the possibility to choose one, two or no insurance in his doctor space.But I have a problem, when the doctor is not affiliated with any insurance, I want to choose a default value showing that this doctor does not have insurance yet, but whatever I choose that is not insurance does not take effect.
Controller
public function editAction(Request $request)
{
$user = $this->getUser();
if (null === $user) {
throw new NotFoundHttpException('Utilisateur Inexistant');
}
$em = $this->getDoctrine()->getManager();
$repo = $em->getRepository('DoctixMedecinBundle:Medecin');
$specialiteRepo = $em->getRepository('DoctixAdminBundle:Specialite');
$cliniqueRepo = $em->getRepository('DoctixAdminBundle:Clinique');
$assuranceRepo = $em->getRepository('DoctixMedecinBundle:Assurance');
$object = $assuranceRepo->findOneBy(['id' => $request->get('assurance')]);
$medecin = $repo->findOneBy([
'user' => $user,
]);
if ($request->isMethod('POST')) {
if ('' != ($pass = $request->get('pass'))) {
$medecin->getUser()->setSalt('');
$factory = $this->get('security.encoder_factory');
$encoder = $factory->getEncoder($medecin->getUser());
$password_encoder = $encoder->encodePassword($pass, $medecin->getUser()->getSalt());
$medecin->getUser()->setPassword($password_encoder);
}
$medecin->setSpecialite($specialiteRepo->find($request->get('specialite')));
$medecin->setClinique($cliniqueRepo->find($request->get('clinique')));
$medecin->getUser()->setAdresse($request->get('adresse'));
$medecin->getUser()->setNumTel($request->get('telephone'));
$medecin->setQuartier($request->get('quartier'));
$medecin->setNumOrdre($request->get('numordre'));
if ($object) {
$medecin->addAssurance($object);
}
$em->persist($medecin);
$em->flush();
// redirection avec le status http 301 ::)))))
$url = $this->generateUrl('medecin_parametre');
return $this->redirect($url, 301);
} else {
return $this->render('DoctixMedecinBundle:Medecin:editProfile.html.twig', [
'medecin' => $medecin,
'specialites' => $specialiteRepo->findAll(),
'cliniques' => $cliniqueRepo->findAll(),
'assurances' => $assuranceRepo->findAll(),
]);
}
}
Twig
<div class="col-md-6">
<div class="form-group">
<label for="assurance" class="control-label">Assurance </label>
<select id="assurance" class="form-control" placeholder="Assurance" name="assurance" multiple>
<option value="Pas d Assurance" selected="Pas encore">Pas d'Assurance</option>
{% for assurance in assurances %}
<option value="{{ assurance.id }}"
{% for it in medecin.assurance %}
{{ it.id== assurance.id ?
'selected' : '' }}
{% endfor %} >{{ assurance.nom|upper }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="row">
<div class="col-md-offset-3 col-md-3">
<input type="submit" class="btn_1 btn-success medium" form="editProfil" value="Valider">
Annuler
</div>
</div>
twig view where will be displayed or not the insurance to which the doctor is affiliated
<div class="col-md-6">
<div class="form-group">
<label>Vos Assurances</label>
{% for item in medecin.assurance %}
{% if item is not empty %}
<input type="text" class="form-control" readonly
placeholder="{{ item.nom|upper }} ">
{% else %}
<input type="text" class="form-control" readonly
placeholder="Vous n'avez pas d'assurance ">
{% endif %}
{% endfor %}
</div>
</div>
Now how to display like a paragraph saying No insurance when the doctor does not have insurance ?
Thanks.

To check if the medicin have an any assurances you'll have to check if the array medecin.assurance is empty or not
Something like this:
{% if medecin.assurance is empty %}
{# This medecin has no assurances, act accordingly #}
{% else %}
{# Display medecin's assurances #}
{% for item in medecin.assurance %}
{# Display each assurance #}
{% endfor %}
{% endif %}

Related

sending data from a "form action" to a views function in django

How are you community, I'm a little confused between my newbies and lack of knowledge, I'm working on a small project in Django and I'm also trying to send data from a form action in the html to another view function but I'm not understanding it well How does this work and on top of that I have to send several data not just one and it confuses me even more, I have the following HTML:
{% extends "base.html" %}
{% block content %}
<main class="container">
<div class="row">
<div class="col-md-10 offset-md-1 mt-5">
<form action="/interface/" method="POST" class="card card-body">
<h1>Interface</h1>
<h4>{{ error }}</h4>
<select name="dv">
<option selected disabled="True">Select Device</option>
{% for device in devicess %}
<option>{{ device.id }} - {{ device.name }}</option>
{% endfor %}
</select>
<br>
{% csrf_token %}
<br>
<button type="submit" class="btn btn-primary">Send</button>
</form>
<br>
{% for interface in interfaces %}
<section class="card card-body">
<h2>{{interface.Interface}}</h2>
{% if interface.Description == "" %}
<p class="text-secondary">none description</p>
{% else %}
<P class="text-secondary">{{interface.Description}}</P>
{% endif %}
<form action= "{% url 'send_description' %}"method="POST">
{% csrf_token %}
<input type="text" name="command" class="form-control" placeholder="Change description">
<br>
<button type="submit" class="btn btn-primary align-content-lg-center">Send change</button>
</form>
<br>
{% if interface.Status == "up" %}
<p class="text-secondary">Interface State: 🟢 Free</p>
{% else %}
<p class="text-secondary">Interface State: 🔴 Used</p>
{% endif %}
</section>
<br>
{% endfor %}
</div>
</div>
</main>
{% endblock %}
and aesthetically to better understand the first POST executed like this:
So far everything is perfect, if I press the "Send change" button it redirects me perfectly, the problem is that I need to send various data such as device.id, interface to that function that I am executing in the action= "{% url 'send_description' %} .Interface and also the content of the input that is inside the same form. Could you give me a hand or a guide on where to find the best way?
regards!
Let me start by saying that this would work way better with JS and AJAX. But, to answer your question, data is passed via Django http request object, in your case, since you have several different forms, it is possible to pass this data by adding a hidden field inside each form with the desired value:
<input type="hidden" name="interface" value="{{ interface.id }}">
And fetch this value form the request object in the view:
interface = request.POST.get('interface')
A full example:
models.py
class Device(models.Model):
name = models.CharField(max_length=100)
class Interface(models.Model):
name = models.CharField(max_length=100)
description = models.CharField(max_length=100, default='interface description field')
status = models.BooleanField(default=False)
device = models.ForeignKey(Device, on_delete=models.CASCADE, related_name='interfaces')
views.py
from django.core.exceptions import ObjectDoesNotExist
def list_interfaces(request):
devices = Device.objects.all()
interfaces = None
try:
selected_device = Device.objects.get(id=request.POST.get('dv'))
interfaces = selected_device.interfaces.all()
except ObjectDoesNotExist:
selected_device = Device.objects.all().first()
if selected_device:
interfaces = selected_device.interfaces.all()
else:
selected_device = None
context = {
'devices': devices,
'selected_device': selected_device,
'interfaces': interfaces
}
return render(request, 'list_device_interfaces.html', context)
def send_description(request):
command = request.POST.get('command')
device = request.POST.get('seleted_device')
interface = request.POST.get('interface')
print(f'command: {command}')
print(f'device_id: {device}')
print(f'device_id: {interface}')
return redirect('core:list-device-interfaces')
urls.py
from core import views
from django.urls import path
app_name = 'core'
urlpatterns = [
path("list/device/interfaces/" , views.list_interfaces, name="list-device-interfaces"),
path("send/description/" , views.send_description, name="send-description"),
]
list_device_interfaces.html
{% extends "base.html" %}
{% block content %}
<main class="container">
<div class="row">
<div class="col-md-10 offset-md-1 mt-5">
<form action="{% url 'core:list-device-interfaces' %}" method="POST" class="card card-body">
{% csrf_token %}
<h1>Device</h1>
<h4>{{ error }}</h4>
<select name="dv">
<option selected disabled="True">Select Device</option>
{% for device in devices %}
<option value="{{ device.id }}" {% if device.id == selected_device.id %} selected {% endif %}>{{ device.id }} - {{ device.name }}</option>
{% endfor %}
</select>
<br>
<br>
<button type="submit" class="btn btn-primary">Send</button>
</form>
<br>
<hr>
<h2>Interfaces</h2>
{% for interface in interfaces %}
<section class="card card-body">
<h2>{{interface.name}}</h2>
{% if interface.description == "" %}
<p class="text-secondary">none description</p>
{% else %}
<P class="text-secondary">{{interface.description}}</P>
{% endif %}
<form action= "{% url 'core:send-description' %}"method="POST">
{% csrf_token %}
<input type="text" name="command" class="form-control" placeholder="Change description">
<input type="hidden" name="seleted_device" value="{{ selected_device.id }}">
<input type="hidden" name="interface" value="{{ interface.id }}">
<br>
<button type="submit" class="btn btn-primary align-content-lg-center">Send change</button>
</form>
<br>
{% if interface.status %}
<p class="text-secondary">Interface State: 🟢 Free</p>
{% else %}
<p class="text-secondary">Interface State: 🔴 Used</p>
{% endif %}
</section>
<br>
{% endfor %}
</div>
</div>
</main>
{% endblock %}

How to make option tag in HTML display rows of one column but save values of another from the same table

I am trying to make a calorie counter app using flask/python-anywhere, and part of it is making a drop down menu of foods to choose from. I want the user to be able to see the food name, but when they submit the food, it's the food's calories that I want to be added to the database.
This is the python code for the relevant tables:
class Post(db.Model):
__tablename__ = "posts"
id = db.Column(db.Integer, primary_key=True)
calories = db.Column(db.Integer)
timestamp = db.Column(db.DateTime, index=True, default=datetime.now)
consumer_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=True)
consumer = db.relationship('User', foreign_keys=consumer_id)
class Food(db.Model):
__tablename__ = "foods"
id = db.Column(db.Integer, primary_key=True)
food_name = db.Column(db.String(200))
food_cal = db.Column(db.Integer)
This is the python code for the page:
#app.route("/", methods=["GET", "POST"])
#login_required
def index():
if request.method == "GET":
return render_template("main_page.html", foods=Food.query.all(), posts=Post.query.all(), timestamp=datetime.now())
if not current_user.is_authenticated:
return redirect(url_for('index'))
add_food = Post(calories=request.form["calories"], consumer=current_user)
db.session.add(add_food)
db.session.commit()
return redirect(url_for('index'))
and this is my html code:
<div class="container">
{% for post in posts %}
<div class="row" style="margin-bottom: 1ex">
<div>
You added {{ post.calories }} calories
</div>
<div>
<small>
at
{% if post.timestamp %}
{{ post.timestamp.strftime("%A, %d %B %Y at %H:%M") }}
{% else %}
at an unknown time
{% endif %}
</small>
</div>
</div>
{% endfor %}
{% if current_user.is_authenticated %}
<div class="row">
<form action="." method="POST">
<div class="form-group">
<label for="foods">Food:</label>
<select class="form control" name="food_name">
{% for food in foods %}
<option value = "{{ food.food_name }}" selected>{{ food.food_name }}</option>
{% endfor %}
</select>
<input type="submit" class="btn btn-success" value="Add calories">
</div>
</form>
</div>
{% endif %}
</div><!-- /.container -->
Just to clarify, the foods in the Food table have been added on my end, but I want the foods that users select to be saved as 'calories' in my Post table. Thanks in advance :)
<option value = "{{ food.food_name }}" selected>{{ food.food_name }}</option>
should be
<option value = {{ food.food_cal }} selected>{{ food.food_name }}</option>

Get url argument to process generic views

I would like to write a one-template view, which depending on the url path will show different field of the model. So for instance if path is
http://127.0.0.1:8000/trip/2/1/
I will get second trip from my db (that works), and 1 should give (as html is written) a description field. I don't know how to process this to context_processor in my view. Do you have any ideas?
views.py
class TripDescriptionCreate(LoginRequiredMixin, UpdateView):
model = Trip
template_name = 'tripplanner/trip_arguments.html'
fields = ["description", "city", "country", "climate", "currency", "food", "cost", "comment", "accomodation",
"car", "flight", "visa", "insurance", "remarks"]
context_object_name = 'trips'
success_url = '/'
def form_valid(self, form):
form.instance.author = self.request.user
return super().form_valid(form)
trip_arguments.html
<form method="POST">
{% csrf_token %}
<fieldset class="form-group">
<legend class="border-bottom mb-4">{{ trips.tripName }}</legend>
{% if field_id == 1 %}
{{ form.description|as_crispy_field }}
{% elif field_id == 2 %}
{{ form.city|as_crispy_field }}
{% endif %}
</fieldset>
<div class="form-group">
<button class="btn btn-outline-info" type="submit">Update</button>
</div>
</form>
urls.py
path('trip/<int:pk>/<int:field_id>', TripDescriptionCreate.as_view(), name='trip-fullfill'),
So I came up with this idea. In my html I added these lines:
{% url 'trip-fullfill-description' pk=trip.pk as description_url %}
{% url 'trip-fullfill-city' pk=trip.pk as city_url %}
{% if request.get_full_path == description_url %}
{{ form.description|as_crispy_field }}
{% elif request.get_full_path == city_url %}
{{ form.city|as_crispy_field }}

Hide/Show form on button click in Flask

I was learning to create a wtf Flask web form which was:
class Update(FlaskForm):
username = StringField('Username', validators=[DataRequired()])
email = StringField('Email', validators=[DataRequired(), Email()])
pic = FileField('Update Profile Pic', validators=[FileAllowed(['jpg','png'])])
submit = SubmitField('Update')
What I wanted to do was that the form would load on the same page on a button click without making a seperate html page for the form. How can it be done either by using Flask or HTML? If any changes to route have to be made, please mention that as well.
HTML Code:
<div class="content-section">
<form method="POST" action="" enctype="multipart/form-data">
{{ form.hidden_tag() }}
<fieldset class="form-group">
<legend class="border-bottom mb-4">Account Info</legend>
<div class="form-group">
{{ form.username.label(class="form-control-label") }}
{% if form.username.errors %}
{{ form.username(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.username.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.username(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.email.label(class="form-control-label") }}
{% if form.email.errors %}
{{ form.email(class="form-control form-control-lg is-invalid") }}
<div class="invalid-feedback">
{% for error in form.email.errors %}
<span>{{ error }}</span>
{% endfor %}
</div>
{% else %}
{{ form.email(class="form-control form-control-lg") }}
{% endif %}
</div>
<div class="form-group">
{{ form.pic.label() }}
{{ form.pic(class="form-control-file") }}
{% if form.pic.errors %}
{% for error in form.picture.errors %}
<span class="text-danger">{{error}}</span><br>
{% endfor %}
{% endif %}
</div>
</fieldset>
<div class="form-group">
{{ form.submit(class="btn btn-outline-info") }}
</div>
</form>
You can load your form normally, and set it's visibility to hidden. If someone clicks on the button, just change visibility of a form to visible.
Example below:
function toggle_display(){
el = document.querySelector('.content_section');
if(el.style.visibility == 'hidden'){
el.style.visibility = 'visible'
}else{
el.style.visibility = 'hidden'
}
}
<button onclick="toggle_display()">Toggle display</button>
<div class="content_section">See me no more</div>
EDIT:
One more thing to mention, visibility property when set to hidden takes up space, even if it's hidden. To completly remove space that form will take and hide form, set display property to none. To show it again, set display to block.

Using html input tag while iterating over Django fields

I want to iterate over fields list in Django so as to create a generalized template for major of my forms.
The problem I face is that my form is not considered as valid when I'm using the input fields.
I want to stick to input fields as I'm using materialize css .
Below is my
form_template.html
<div class="row ">
{% for field in form %}
<div class="form-group">
{% ifequal field.name "password" %}
<div class="row">
<div class="input-field col s3 xl12">
<input id="{{ field.name }}" type="password" class="{{
field.name }}">
<label for="{{ field.name }}">{{ field.label }}</label>
</div>
</div>
{% endifequal %}
{% ifnotequal field.name "password" %}
{% ifequal field.name "email" %}
<div class="row">
<div class="input-field col s3 xl12">
<input id="{{ field.name }}" type="{{ field.name }}" class="validate">{{ form.field }}
<label for="{{ field.name }}" data-error="Not a valid email"
data-success="Valid Email">{{ field.label }}</label>
</div>
</div>
{% endifequal %}
<br>
{% ifnotequal field.name "email" %}
{% ifequal field.name "album_logo" %}
<div class="file-field input-field col s3 xl12">
<div class="btn">
<span>File</span>
<input type="file" multiple>
</div>
<div class="file-path-wrapper">
<input class="file-path validate" type="text" placeholder="Upload an album cover">
</div>
{% endifequal %}
{% ifnotequal field.name "album_logo" %}
{% ifequal field.name "date_joined" %}
<div class="row">
<div class="input-field col s3 xl12">
<input id="{{ field.name }}" type="date" class="datepicker">{{ form.field }}
<label for="{{ field.name }}">{{ field.label }}</label>
</div>
</div>
{% endifequal %}
{% ifnotequal field.name "date_joined" %}
<div class="row">
<div class="input-field col s3 xl12">
<input id="{{ field.name }}" type="text">
<label for="{{ field.name }}">{{ field.label }}
</label>
</div>
</div>
{% endifnotequal %}
{% endifnotequal %}
{% endifnotequal %}
{% endifnotequal %}
</div>
{% endfor %}
</div>
and UserFormView Class in views.py
class UserFormView(View):
form_class = UserForm
template_name = "music/registration_form.html"
# Display a blank form for a new user
def get(self, request):
form = self.form_class(None)
return render(request, self.template_name, {'form': form})
# Process form Data here
def post(self, request):
form = self.form_class(request.POST)
if form.is_valid():
user = form.save(commit=False)
# Cleaned (Normalized or Formatted) Data
username = form.cleaned_data['username']
password = form.cleaned_data['password']
user.set_password(password)
user.save()
# Returns User Objects if credentials are correct
user = authenticate(username=username, password=password)
if user is not None:
if user.is_active:
login(request,user)
return HttpResponseRedirect('music:index')
else:
return render(request, self.template_name, {'form': form})
Would really appreciate some help, thanks.
When you want to style your form I would suggest to use Widget Tweaks. When you install it correctly you can use it in your template like:
Css:
.inputStyle{
width: 500px;
border: 1px solid black;
border-radius: 5px;
}
.slide{
...
}
HTML:
<form method='POST' action="/" enctype='multipart/form-data'>
{% load widget_tweaks %}
{% csrf_token %}
<span class="">Post the Image via Url: {{form.image_url|add_class:"inputStyle" }}</span>
<span class="" >Please select an option {{ form.Options|add_class:"slide" }}</span>
</form>
Another way to style your forms is to install Widgets in the forms.py
You can install things like Django Select and add it into the form like:
class PostForm(forms.ModelForm):
language = forms.MultipleChoiceField(widget=Select2MultipleWidget(attrs={'data-placeholder': 'Language'}),choices=settings.LANGUAGES)
class Meta:
model = Post
fields=[
'title',
'content',
'image_url',
'language',
.....
]
don't forget to use {{ form.media.js }}in the form.
I hope you get that going. The way you do it now is not the best way ;)
p.s. forgot to mention Django Crispy Form. They are fast to install and easy to handle but I would suggest using widget tweaks since you can style everything with CSS. Crispy can be tricky sometimes and you have to read into the docs...