I am using Symfony2 2.6.4 with the FOS User Bundle (master) and I am having a hard time trying to pass a partial registration from the home page to the registration page.
The Goal
I want a user to start on the home page and fill out some info and press submit. I want the user to be passed to the registration page and pre fill the items that they have already filled out on the front page.
Things I have tried:
I am unsure what is feasable and have already spend too much time on this. I tried extending the registration controller but I am getting errors before I can even start on my issue so I stopped. My last thought was to pass the variables in a session to the overridden registration form type and see if I can pre-populate it there.
Has anyone done anything like this before? They sure don't make it easy.
Credit goes to #NawfalSerrar Thank you for the idea. I was close but not close enough!
So what I ended up doing was this.
This is the controller action that does that work.
/**
* #Route("/", name="Home")
*/
public function indexAction(Request $request)
{
$form = $this->createForm(new RegisterFormType());
$form->handleRequest($request);
if ($form->isValid()) {
$data = $form->getData();
$user = new User();
$session = $this->get('session');
$registration = array();
$registration['firstName'] = $data['first'];
$registration['lastName'] = $data['last'];
$registration['middleInit'] = $data['middle'];
$registration['email'] = $data['email'];
$session->set('registration', $registration);
return $this->redirect($this->generateUrl("fos_user_registration_register"));
}
return $this->render('Bundle:Page:index.html.twig', array(
'form' => $form->createView(),
));
}
Then the form on the front end.
{{ form_start(form,{'attr': {'class': 'reg-page'}}) }}
<div class="reg-header">
<h1>Get Started!</h1>
<p>Already Signed Up? Click Sign In to login
your account.</p>
</div>
{{ form_errors(form) }}
<div class="row">
<div class="col-sm-6">
{{ form_label(form.first) }}
{{ form_widget(form.first, {'attr': {'class': 'form-control margin-bottom-10'}}) }}
</div>
<div class="col-sm-6">
{{ form_label(form.middle) }}
{{ form_widget(form.middle, {'attr': {'class': 'form-control margin-bottom-10'}}) }}
</div>
<div class="col-sm-6">
{{ form_label(form.last) }}
{{ form_widget(form.last, {'attr': {'class': 'form-control margin-bottom-10'}}) }}
</div>
</div>
{{ form_label(form.email) }}
{{ form_widget(form.email, {'attr': {'class': 'form-control'}}) }}
<div class="row">
<div class="col-lg-6 text-right">
{{ form_widget(form.save, {'attr': {'class': 'btn-u'}}) }}
</div>
</div>
{{ form_end(form) }}
Registration page looks like this.
{% extends '::base.html.twig' %}
{% block body %}
{% set tokens = app.session.get('registration') %}
{% if tokens['firstName'] is defined %}
{% set firstName = tokens['firstName'] %}
{% endif %}
{% if tokens['middleInit'] is defined %}
{% set middleInit = tokens['middleInit'] %}
{% endif %}
{% if tokens['lastName'] is defined %}
{% set lastName = tokens['lastName'] %}
{% endif %}
{% if tokens['email'] is defined %}
{% set email = tokens['email'] %}
{% endif %}
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_label(form.firstName, 'First Name', {label_attr: {class: 'foo'}}) }}
{% if firstName is defined %}
{{ form_widget(form.firstName, { attr: {class: 'TestClass'}, value : firstName }) }}
{% else %}
{{ form_widget(form.firstName, { attr: {class: 'TestClass'} }) }}
{% endif %}
{{ form_label(form.middleInitial) }}
{% if middleInitial is defined %}
{{ form_widget(form.middleInitial, { attr: {class: 'TestClass'}, value : middleInit }) }}
{% else %}
{{ form_widget(form.middleInitial, { attr: {class: 'TestClass'}}) }}
{% endif %}
{{ form_label(form.lastName) }}
{% if lastName is defined %}
{{ form_widget(form.lastName, { attr: {class: 'TestClass'}, value : lastName }) }}
{% else %}
{{ form_widget(form.lastName, { attr: {class: 'TestClass'}}) }}
{% endif %}
{{ form_label(form.email) }}
{% if email is defined %}
{{ form_widget(form.email, { attr: {class: 'TestClass'}, value : email }) }}
{% else %}
{{ form_widget(form.email, { attr: {class: 'TestClass'}}) }}
{% endif %}
{{ form_label(form.plainPassword.first) }}
{{ form_widget(form.plainPassword.first) }}
{{ form_label(form.plainPassword.second) }}
{{ form_widget(form.plainPassword.second) }}
<div>
<input type="submit" value="{{ 'registration.submit'|trans }}"/>
</div>
{{ form_end(form) }}
{% endblock %}
Hope this helps!
Related
I overrided my form in EasyAdmin to organize differently my input so I did like this :
In my Crud :
public function configureCrud(Crud $crud): Crud
{
return $crud
->setPageTitle(Crud::PAGE_INDEX, 'admin.menu.infos')
->setFormThemes(['bundles/EasyAdminBundle/crud/company/edit.html.twig'])
;
}
And in my Twig :
{% extends '#EasyAdmin/crud/form_theme.html.twig' %}
{% use '#EasyAdmin/symfony-form-themes/bootstrap_5_layout.html.twig' %}
{% block form %}
{{ form_start(form) }}
<div class="row">
{{ form_row(form.logo) }}
{{ form_row(form.phone) }}
{{ form_row(form.catchphrase) }}
</div>
<div class="row">
{{ form_row(form.businessName) }}
{{ form_row(form.email) }}
{{ form_row(form.website) }}
</div>
<div class="row">
{{ form_row(form.companyName) }}
{{ form_row(form.address) }}
{{ form_row(form.linkedin) }}
</div>
<div class="row">
{{ form_row(form.siren) }}
{{ form_row(form.zipcode) }}
{{ form_row(form.facebook) }}
</div>
<div class="row">
{{ form_row(form.legalForm) }}
{{ form_row(form.city) }}
{{ form_row(form.twitter) }}
</div>
<div class="row">
{{ form_row(form.description) }}
</div>
{{ form_end(form) }}
{% endblock %}
The form is like I wanted and when I submit, it's work but the problem is when I make an error. For example if I valid with an empty value, then instead of getting my form_errors, I've got a 500.
I've tried different things but none of them worked :
block errors :
{{ form_start(form) }}
{% block form_errors %}
{{ parent() }}
{% endblock %}
individual error :
{{ form_errors(form.businessName) }}
Any idea ?
I have 3 entities: User (part of FOSUserBundle), Comment, Article.
I'd like to display a comment form on the article only of the visitor is logged in. It was displaying for everybody just fine.
My code doesn't work and also seems like very bad practice. I get "Variable "form" does not exist." because I'm stopping the form from getting passed to the view. Is the necessary if I put an if in the view? I'd appreciate any suggestions on how I can accomplish this!
Thanks a bunch.
My comment.html.twig
{% extends 'base.html.twig' %}
{% block body %}
{% form_theme form 'form/fields.html.twig' %}
{% if is_granted('ROLE_USER') -%}
<div class="form-group">{{ form_start(form) }}</div>
<div class="form-group">{{ form_row(form.comment.title) }}</div>
<div class="form-group">{{ form_row(form.comment.rating) }}</div>
<div class="form-group">{{ form_row(form.comment.comment) }}</div>
<div class="form-group">{{ form_row(form.comment.user.firstName) }}</div>
<div class="form-group">{{ form_row(form.comment.user.lastName) }}</div>
<div class="form-group">{{ form_row(form.comment.user.email) }}</div>
<input class="btn btn-default" type="submit" value="Create" />
{{ form_end(form) }}
{% else %}
<p>Please log in to post a comment!</p>
{% endif %}
{% endblock %}
My show.html.twig (for articles)
{% extends 'base.html.twig' %}
{% block body_id 'articlepage' %}
{% block body %}
<h1>Article: {{ article.name }}</h1>
<div class="well"><div class="media">
<div class="media-left media-top">
<img class="media-object" src="{{ article.thumbnail }}">
</div>
<div class="media-body">
<h4 class="media-heading">{{ article.name }}</h4>
<p>{{ article.description }}</p>
</div>
</div></div>
<h2>Article Comments:</h2>
{{ render(controller('AppBundle:Comment:index', {'article_id': article.id})) }}
<h2>Submit a new comment:</h2>
{{ render(controller('AppBundle:Article:comment', {'id': article.id})) }}
{% endblock %}
commentAction within ArticleController.php (a controller that gets embedded in the show.html.twig)
public function commentAction(Request $request, Article $article)
{
$auth_checker = $this->get('security.userization_checker');
$token = $this->get('security.token_storage')->getToken();
$user = $token->getUser();
$isRoleUser = $auth_checker->isGranted('ROLE_USER');
if($isRoleUser){
$comment = new Comment();
//Build the comment form.
$commentForm = $this->createFormBuilder($comment)
->add('comment', CommentType::class, array("label" => FALSE))
->setAction($this->generateUrl('article_comment', array('id' =>$article->getId())))
->getForm();
$commentForm->handleRequest($request);
if ($commentForm->isSubmitted() && $commentForm->isValid()) {
//Update existing user or create new
$em = $this->getDoctrine()->getManager();
$comment = $commentForm->getData()->getComment();
$user = $this->getUser($comment->getUser());
//Update the existing comment or get a new one
$user = $this->getUser($comment->getUser());
$comment = $this->getComment($user, $article, $comment);
//Set the user and article for the comment.
$comment->setUser($user);
$comment->setArticle($article);
$em->persist($comment);
$em->flush($comment);
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('article_show', array('id' => $article->getId()));
}
return $this->render('article/comment.html.twig', array(
'form' => $commentForm->createView(),
));
} else {
return $this->render('article/comment.html.twig');
}
}
If you want to check whether user logged in or not in your Twig templates, you could use app.user variable:
{% if app.user %}
{{ render(controller('AppBundle:Comment:index', {'article_id': article.id})) }}
{% endif %}
In my Symfony 2 app I got the following code rendering the form:
{{ form_start(form) }}
{{ form_errors(form) }}
<div class="form-group">
{{ form_label(form.title) }}
{{ form_widget(form.title) }}
</div>
<div class="form-group">
{{ form_label(form.message) }}
{{ form_widget(form.message) }}
</div>
{% if extras == true %} //this block should be rendered only if extras var is true
<div class="form-group">
{{ form_label(form.description) }}
{{ form_widget(form.description) }}
</div>
{% endif %}
{{ form_end(form) }}
The problem is that I get rendered {{ form_widget(form.description) }} even if my extras var is false, not with all other form fields but somewhere at the bottom of the form which is obviously a bug. How to make it render only if extras is true and disappear completely from the page in case extras is false?
Thank you.
All other form fields are automatically added to the end of your form by default. It triggers {{ form_rest() }} by default. Use this code to prevent this behavior:
{{ form_end(form, {'render_rest': false}) }}
http://symfony.com/doc/current/reference/forms/twig_reference.html#form-end-view-variables
I'm creating a form in Symfony2 that contains more than one submit button. I need to control where these buttons are rendered. I tried the following, but naturally nothing happens.
<h1>Search Form</h1>
<div id="search_form">
{{ form(formSearch) }}
</div>
<div id="search_tasks">
Tasks:
{{ form_widget(formSearch.searchButton1) }}
{{ form_widget(formSearch.searchButton2) }}
</div>
The search buttons are declared in the form class; they are rendered inside #search_form and nothing shows up in #search_tasks.
You are already rendering the whole form with {{ form(formSearch) }} (fields and buttons are only rendered once).
You need to render the start, rows and end separately.
{{ form_start(formSearch) }}
<h1>Search Form</h1>
<div id="search_form">
{{ form_row(formSearch.field1) }}
{{ form_row(formSearch.field2) }}
{{ form_row(formSearch.field3) }}
</div>
<div id="search_tasks">
Tasks:
{{ form_widget(formSearch.searchButton1) }}
{{ form_widget(formSearch.searchButton2) }}
</div>
{{ form_end(formSearch) }}
I ran into the same issue where I needed my Submit and Reset buttons to be on the same row. My forms are dynamic so there was no way I could output the fields individually. I captured the buttons' HTML first so that form_widget(form) wouldn't output them for me.
{% form_theme form 'AppBundle::form/form_layout.html.twig' %}
<div class="row">
{{ form_start(form) }}
{% if form.submit is defined %}
{% set submitButton = form_widget(form.submit) %}
{% endif %}
{% if form.reset is defined %}
{% set resetButton = form_widget(form.reset) %}
{% endif %}
{{ form_widget(form) }}
<div class="form-group row">
{% if submitButton is defined %}
{{ submitButton|raw }}
{% endif %}
{% if resetButton is defined %}
{{ resetButton|raw }}
{% endif %}
</div>
{{ form_end(form) }}
</div>
Using this manual, I added dynamic field to my form. Now, how can I check existence of this field in my template?
{{ form_start(form) }}
{{ form_errors(form) }}
{% if ??? %} <---------------------------
{{ form_row(form.myDynamicField) }}
{% endif %}
{{ form_end(form) }}
What about,
{% if form.myDynamicField is defined %}
{{ form_row(form.myDynamicField) }}
{% endif %}
You may also need to check if form.myDynamicField is not null.
I know this question is a few years old, but you could also make it a shorter ternary operator.
{{ form.myDynamicField is defined ? form_row(form.myDynamicField) : null }}
{{ form_start(form) }}
{{ form_errors(form) }}
{% if form.getChildren['myDynamicField'] is defined %}
{{ form_row(form.myDynamicField) }}
{% endif %}
{{ form_end(form) }}