How to display a zend-form element select in twig template?
Do as follows:
Form:
$this->add([
'name' => 'parent',
'type' => 'Zend\Form\Element\Select',
'options' => [
'label' => 'Принадлежность',
'empty_option' => 'Выберите категорию',
'value_options' => [
'0' => 'French',
'1' => 'English',
'2' => 'Japanese',
'3' => 'Chinese',
],
],
]);
Twig:
<div class="form-group select">
<label for="{{ form.get('parent').name }}">{{ form.get('parent').label }}</label>
<select class="form-control" type="{{ form.get('parent').attributes.type }}" name="{{ form.get('parent').name }}">
<option>{{ form.get('parent').options.value_options }}</option>
</select>
</div>
You should be able to achieve it with something like this:
<div class="form-group select">
<label for="{{ form.get('parent').name }}">{{ form.get('parent').label }}</label>
<select class="form-control" type="{{ form.get('parent').attributes.type }}" name="{{ form.get('parent').name }}">
{% for option in form.get('parent').options.value_options %}
<option>{{ option }}</option>
{% endfor %}
</select>
</div>
Since I haven't used twing I can't be sure.
Read more about twig for loop here.
Related
I wanted to modify the way my forms is displayed using html and css.
Here is the <form> part of my HTML:
<form action="" method="post" enctype='multipart/form-data'>
{% csrf_token %}
<div>
<input type="text" name="post_title" placeholder="Forum title" id="id_post_title">
<textarea name="post_body" placeholder="Forum content" id="id_post_body"></textarea>
<div class="authors"> <!-- This class is to call my Users model -->
<select name="author" id="id_author">
<option value="">----Select Author----</option>
{% for author in authors %}
<option value="{{ author.first_name }} {{ author.last_name }}">{{ author.first_name }} {{ author.last_name }}</option>
{% endfor %}
</select>
</div>
<div>
<label>
<input type="file" accept="image/" name="forum_image" required id="id_forum_image" >Upload Image
</label>
</div>
<input type="submit" value="Save Post" class="save_post">
</div>
</form>
I tried form.as_p and it all worked just fine. Did I made a mistake in my HTML? Here is my forms.py:
class AddForum(forms.ModelForm):
class Meta:
model = Forum
fields = 'all'
labels = {
'post_title': 'Title of your post:',
'post_body': 'Content of your post:',
'author': 'Author:',
'forum_image': 'Attach image:',
}
def __init__(self, *args, **kwargs):
super(AddForum, self).__init__(*args, **kwargs)
self.fields['forum_image'].required = False
The problem lies with my <option value="{{ something }}". What value needs is {{ something }}'s id and not the name itself.
The code should be:
<option value="{{ author.id }}">{{author.first_name }} {{ author.last_name }}</option>
I'm using Django's generic editing views CreateView, UpdateView, etc. together with the auto-generated HTML forms and it works fine:
# views.py
class TagCreate(CreateView):
template_name = 'app/tag_form.html'
model = Tag
fields = ['name', 'description', 'color']
class TagUpdate(UpdateView):
model = Tag
fields = ['name', 'description', 'color']
<!-- app/tag_form.html -->
{% extends 'app/base.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Save">
</form>
{% endblock %}
Now, I want to customize the generated form {{ form.as_p }} with bootstrap:
{% extends 'app/base.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label for="nameInput">Name</label>
<input class="form-control" type="text" id="nameInput" placeholder="Name" value="{{ tag.name }}">
</div>
<div class="form-group">
<label for="descrInput">Description</label>
<input class="form-control" type="text" id="descrInput" placeholder="Description" value="{{ tag.description }}">
</div>
<div class="form-group">
<label for="colorInput">Color</label>
<input class="form-control" type="color" id="colorInput" placeholder="Color" value="{{ tag.color }}">
</div>
<input type="submit" value="Save">
</form>
{% endblock %}
The page renders nicely exactly how I want it to, but when I click the "Save" button, nothing happens and the data is no longer saved, nor am I forwarded to the detail view like I was before.
I tried following the Django documentation on how to render fields manually; again, it's rendered correctly, but the data isn't saved.
How can I properly customize forms and still use my generic editing views?
Edit: My full code his here.
Following the documentation you have to access the form inputs manually and django will populate them accordingly in the template.
{% extends 'app/base.html' %}
{% block content %}
<form method="post">
{% csrf_token %}
<div class="form-group">
<label for="nameInput">Name</label>
{{ form.name }}
</div>
<div class="form-group">
<label for="descrInput">Description</label>
{{ form.description }}
</div>
<div class="form-group">
<label for="colorInput">Color</label>
{{ form.color }}
</div>
<input type="submit" value="Save">
</form>
{% endblock %}
From there, to add classes, you will have to override the CreateView get_form in order to add in what we need:
class TagCreate(CreateView):
template_name = 'app/tag_form.html'
model = Tag
fields = ['name', 'description', 'color']
def get_form(self, form_class):
form = super(TagCreate, self).get_form(form_class)
form.fields['name'].widget = forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Name' })
form.fields['description'].widget = forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Description' })
form.fields['color'].widget = forms.TextInput(attrs={'class': 'form-control', 'placeholder': 'Color' })
return form
Although, this would be a lot cleaner if using ModelForms
in your form input tag set the "name" attribute, field name as value
something like this:
...
<input class="form-control" type="text" id="nameInput" placeholder="Name" name="name" value="{{ tag.name }}">
...
<input class="form-control" type="text" id="descrInput" placeholder="Description" name="description" value="{{ tag.description }}">
...
<input class="form-control" type="color" id="colorInput" placeholder="Color" name="color" value="{{ tag.color }}">
...
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 %}
I am trying to input number in a form (laravel 5.4) but the code is not working.
I have tried different options but it is not working.
<div class="col-md-4 col-md-offset-2">
{!! Form::open(array('route' => 'properties.store', 'data-parsley-validate' => '' , 'files' => true)) !!}
{{ Form::label('address', 'Address:') }}
{{ Form::text('address', null, array('class'=>'form-control', 'placeholder'=>'Street & Number')) }}
</div>
<div class="col-md-4">
{{ Form::label('price_paid', "Price Paid:") }}
{{ Form::number('fuel',null, ['class' => 'form-control']) }}
{{ Form::label('loan_ltv', "Loan to Value:") }}
{{ Form::input('number', 'amount', null, ['class' => 'form-control']) }}
{{ Form::label('rent', "Rent Achievable:") }}
{{ Form::number('name', 'value', ['class' => 'form-control']) }}
{{ Form::label('mortgage', "Mortgage Rate:") }}
{{ Form::number('name', 'value', ['class' => 'form-control']) }}
{{ Form::label('management_moe', "Management and Operating Expenses:") }}
{{ Form::number('name', 'value', ['class' => 'form-control']) }}
{{ Form::submit('Create Property Case', array('class' => 'btn btn-success btn-lg btn-block', 'style' => 'margin-top: 20px;')) }}
</div>
{!! Form::close() !!}
</div>
I have tried different options I found here but it is not working.
public function store(Request $request)
{
//validate the data
$this->validate($request, array(
'address' =>'max:255|nullable',
'price_paid' => 'integer|nullable',
'loan_ltv' => 'integer|nullable',
'rent' => 'integer|nullable',
'mortgage' => 'integer|nullable',
'management_moe' => 'integer|nullable'
));
When I submit the form, the only thing I see in the database is the street name and the street number. The rest of the rows has nulls.
I can manually input number in the database but I want to do it through the form. Can someone help me???
This is the working code I use after a lot of research:
{{ Form::label('price_paid', "Price Paid:") }}
{{ Form::number('price_paid', null, ['class' => 'form-control']) }}
{{ Form::label('loan_ltv', "Loan to Value:") }}
{{ Form::number('loan_ltv', null, ['class' => 'form-control']) }}
{{ Form::label('rent', "Rent Achievable:") }}
{{ Form::number('rent', null, ['class' => 'form-control']) }}
{{ Form::label('mortgage', "Mortgage Rate:") }}
{{ Form::number('mortgage', null, ['class' => 'form-control']) }}
{{ Form::label('management_moe', "Management and Operating Expenses:") }}
{{ Form::number('management_moe', null, ['class' => 'form-control']) }}
How can be implemented HTML5 datalist with values from the database (Doctrine)?
Purpose: replace selects with many options to inputs with autocompletion.
First, add your new FormType for the field:.
<?php
// src/Acme/Form/Type/DatalistType
namespace Acme\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormView;
use Symfony\Component\OptionsResolver\OptionsResolver;
class DatalistType extends AbstractType
{
public function getParent()
{
return TextType::class;
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setRequired(['choices']);
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['choices'] = $options['choices'];
}
public function getName()
{
return 'datalist';
}
}
In services.yml:
form.type.datalist_type:
class: Acme\Form\Type\DatalistType
tags:
- { name: form.type, alias: datalist }
Do you have a form theme? If yes, skip to the next step, if no, create a new one in app/Resources/views/Form/fields.html.twig and change your default Twig theme to it:
# app/config/config.yml
twig:
form_themes:
- ':Form:fields.html.twig'
Now define a template for your new field in the form theme:
{% block datalist_widget %}
<input list="{{ id }}_list" {{ block('widget_attributes') }}{% if value is not empty %}value="{{ value }}"{% endif %}>
<datalist id="{{ id }}_list">
{% for choice in choices %}
<option value="{{ choice }}"></option>
{% endfor %}
</datalist>
{% endblock %}
Use your field in FormType:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('country', DatalistType::class, ['choices' => ['a', 'b']]);
}
Instead of ['a', 'b'] You need to load your choices from DB somehow, I'd suggest passing them in form options as the easiest solution.
I spent some time trying to solve this issue, and there is a quite simple solution which solves Konstantin's issue with database access. It is to create a new form type which has EntityType as it's parent.
class DatalistType extends AbstractType
{
public function getParent() {
return EntityType::class;
}
}
You can then create a new template for this widget:
{# views/form/fields.html.twig #}
{% block datalist_widget %}
<input {{ block('widget_attributes') }} list="{{ form.vars.id }}_list" value="{{ form.vars.value }}" />
<datalist id="{{ form.vars.id }}_list">
{% for choice in choices %}
<option>
{{ choice.label }}
</option>
{% endfor %}
</datalist>
{% endblock %}
Finally, in the buildForm function of the form you are building, you can add your form element using the DatalistType, and using the EntityType options.
$builder->add('fieldName', DatalistType::class ,
array('required' => false,
'label' => 'fieldLabel',
'class' => 'AppBundle\Entity\EntityName',
'choice_label' => 'entityField'))
In your formType :
->add('commerciaux', TextType::class,
[
'label' => 'Apporteur d\'affaire*',
'attr' =>
[
'placeholder' => 'Apporteur d\'affaire',
'list' => 'bieres'
]
]
)
In your View :
{{ form_row(formulaire.commerciaux) }}
<datalist id="bieres">
<option value="Meteor">
<option value="Pils">
<option value="Kronenbourg">
<option value="Grimbergen">
</datalist>
In your formType :
->add('commerciaux', TextType::class,
[
'label' => 'Apporteur d\'affaire*',
'attr' =>
[
'placeholder' => 'Apporteur d\'affaire',
'list' => 'bieres'
]
]
)
Declare ( controller or View)
'bieres' => $array_bieres
In your View :
{{ form_row(formulaire.commerciaux) }}
<datalist id="bieres">
{% for biere in bieres %}
<option value="{{ biere }}">
{% endfor %}
</datalist>