How to render only one field of a form with symfony - symfony

I want to render only one field of a form. When i put {{form_end(form)}} every other field are coming (symfony doc show it clearly) but how to render only one field ? If i dont put {{form_end(form)}}, there is only one field, but no save button
thanks

Yes, CSS can do the trick. But do you want the working of your application to depend on client side styling rules? In most cases it might beter not to render the field HTML at all.
There are two ways in which you can fix this in your template.
Put {% do form.field_you_want_to_hide.setRendered %} before your {{form_end(form)}}.
This will mark the field as rendered and thus it will not show up when form_rest is called.
Instead of {{form_end(form)}}, use {{ form_end(form, {'render_rest': false}) }}, as explained in the Symfony Twig documentation.
It would be even better to change your form class such that the fields are removed from your form. Is it your own form you would like to render, or a form from a third party bundle?

Related

Bootstrap not rendering Flask-WTForms QuerySelectField as HTML <select>

I'm trying to build a Flask form with one field being a QuerySelectField. Everything works, except that Bootstrap is rendering the <select> to look like a text input field.
When I look at my page source, I see that the field is rendering as <select class="form-control"...>. If I've read the Bootstrap docs aright, I need to change this to <select class="form-select...>. I've tried putting both render_kw={'class': 'form-select'} and extra_classes='form-select' in my form class, but the latter throws an Unexpected Keyword exception and the former seems to be ignored.
How do I get my SelectField to render as a <select> field?
I resolved this problem by switching from Flask-Bootstrap to Bootstrap-Flask, as the former has not been updated for several years. This also required changing {% import "bootstrap/wtf.html" as wtf %} to {% import "bootstrap/form.html" as wtf %} in my templates, as well as replacing calls to wtf.quick_form() with calls to wtf.render_form().

Django: One template or two templates for different CSS?

I am making a website in Django for an online multiple-choice test. For each question, the question text is displayed on the webpage, together with a set of radio buttons for the possible answers, and a submit button. The user chooses on of the answers, and presses the button. Then, I want to give feedback to the user: A green "Correct", or a red "Incorrect", together with a button to retrieve the next question.
What is the best way to do this in Django? I could have two templates: one for the question, and one for the feedback, and each with one associated view function. For the question, I would pass variables for the question text, together with the text for the possible answers. This seems to work well. However, for the feedback, I would pass the text "Correct" or "Incorrect" as a variable, but how do I now change the CSS to set the text to be green if "Correct", and red if "Incorrect"? Would it be more sensible to have a separate template for the "Correct" case, and the "Incorrect" case?
Thank you.
The Django view should pass whether the answer is correct or not, i.e. a boolean.
Suppose the boolean variable in the template context is called correct; your template code could be something along these lines:
{% if correct %}
// correct html markup in here
<span class="correct">Correct!</span>
{% else %}
// incorrect html markup in here
<span class="incorrect">Woops, not correct!</span>
{% endif %}
The above should all go in the same template, i.e. one template only.

Can't render an action in base layout and execute it from child template

Am working on a Symfony2 application whose among its functions will allow the user to select to visit different sections of the site, and this from anywhere (any page) of the site. For simplifying let's say: when a user want to sort he/she choose from a drop down select form and submit.
I built the action and template with a test root to verify this function and this work (when I use directly the rendering of that sortAction() on my app_dev/test adress.
The issu is that when I try to make this action accessible from the general template (app/Resources/views/base.html) I can view the select form with default view, but when I select for a sort and try to Submit page relaods and return to the defaut view.
I use {% render "MycompanyMybundleBundle:Mycontroller:sort" %} in .../base.html and I want this action to work on (like) mysite/anypage this last extending bundle layout which (layout also extent base).
Can anyone help me?
The description of your problem isn't realy clear, but I think the problem lies at the form action. Do you've configured this action? You should leave it empty if you want to submit it to the same page.
Another solution would be to make use of the extending posibilities of Twig. Define the form as a block in the parent, and override it in the child.
http://twig.sensiolabs.org/doc/tags/extends.html
EDIT:
You could make the form action a block, that is what I mean...
<form action="{% block formAction %}defaulttargetpage.php{ %endblock% }"> <!-- formcontent --> </form>

FOSUserBundle: Change Password within actual project

I have successfully installed FOSUserBundle in my project and everything works as expected. However, I am struggling with how to implement it in my actual project.
I want to create the following setup:
A page displaying some user settings in one form (like newsletter subscription), the possibility to change the password in a second form and maybe also a third form to change the username.
The settings form as well as some more information is coming from an existing action in my controller and is working well.
I did try a few things but things are not really working out yet:
I copied some functionality from FOSUserBundle\Controller\ChangePasswordController\changePasswordAction() to my own action. This way I could get the change password form, create the view and pass it to my template.
I added the form to my template with {{ form_widget(form) }}. The form is being displayed and it's even working. I can change the password. However, the labels are being lost, simply reading Current, First, and Second. Also there is no error messaging showing up when the two new passwords don't match or are being left empty.
Over all I have the feeling I am probably doing this in a wrong way. Could you please help me how I should handle this task and point out where I am likely doing something stupid?
Here is the code of my action, reduced to what's important here:
# src/Acme/MyBundle/Controller/BackendController.php
public function accountAction(){
//pretty much a copy of FOSUserBundle\Controller\ChangePasswordController\changePasswordAction()
$user = $this->get('security.context')->getToken()->getUser();
$form = $this->container->get('fos_user.change_password.form');
$formHandler = $this->container->get('fos_user.change_password.form.handler');
$process = $formHandler->process($user);
if ($process) {
//password has been changed, response will be generated
}
//more stuff going on here
$moreStuff = ...
//render view
return $this->render('AcmeMyBundle:Backend:account.html.twig', array(
'form' => $form->createView(),
'moreStuff' => $moreStuff
));
}
IMO rendering more than one form in one action is not a good idea.
Always try to separate things and let an action handle only one feature.
In your twig template I suggest to use the render method :
{% render 'AcmeBundle:SomeAction' with{'param:param} %}
It will generate a GET request on the action provided with some params if needed.
Create one action that will render the twig template with subrequests :
// AcmeUserBundle:editAction
{% render 'AcmeUserBundle:changePasswordAction' %}
{% render 'AcmeUserBundle:settingsAction' %}
{% render 'AcmeUserBundle:profileAction' %}
And then you'll need to create one action per form.
For password and username modification you can also override FOSUserBundle views if your needs are only visual. If you need to add/remove a field on the form you will need to create a new service.
I sugget reading FOSUserBundle documentation about overriding :
https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/index.md#next-steps

How to remove inputs/fields created by a form in Django

I have a simple form for uploading a profile picture and then a thumbnail image showing what has been uploaded. The HTML code is:
<form action="{% url 'base-welcome' %}" enctype="multipart/form-data" method="post">
{% csrf_token %}
<ul>
<li><span>Upload A Profile Picture:</span> <img src="{{ user.profile.get_thumbnail }}">{{ profile_form.picture }}</li> , then closing elements, etc..
The problem is that the form is creating unwanted elements in the "li". See the following image:
The "currently" and "change" have been created. I've already hidden a checkbox that was created using display: none. I can't really do that with these elements because they are just text that was generated.
I think this is a problem with the models.py/views.py pages, but I may be wrong. Just looking for a simple HTML/CSS fix. Thank you so much!!
It looks like picture field is using ClearableFileInput widget. To use standard FileInput widget (without these extra words and checkbox), do just in your form:
picture = forms.ImageField(upload_to='/path/', widget=forms.FileInput)
In that case you just have to render your forms manually :)
You could either write your own helpers - I can see this as ie. custom filters: {{ form.field|as_file_input_field }} or you could use some external helpers like: http://djangopackages.com/grids/g/forms/
I would still suggest writing your own helpers just to learn how django forms renderer works :)
You could also take a look here for some samples of how we tried to solved this problem while before: https://github.com/efabryka/django-template_widgets :)
This is how the ImageField default widget is rendered - maybe it will be worth your while: https://github.com/django/django/blob/master/django/forms/widgets.py#L298
Are you just wanting to hide some text? I haven't touched HTML/CSS in a while but can't you just put the text inside a div or a span and then hide that?
set color: white; for that element, then all text will be "invisible" lol.

Resources