I am new to Symfony2.0. I am learning it from the site http://symfony.com/doc/2.0/book/index.html. I've gone through all the topics given in the site but i am not getting output for the topic 'Embedding a Single Object',which is included within the Topic of Forms (http://symfony.com/doc/2.0/book/forms.html). I wrote all the code as they have given for 'Embedding a Single Object' but it does not make an entry to the database. When i submit my form it gives me error i stated below. I can make an entry without using embedding object code.
Error : "Catchable Fatal Error: Argument 1 passed to Acme\TaskBundle\Entity\Task::setCategory() must be an instance of Acme\TaskBundle\Entity\Category, array given, called in /opt/lampp/htdocs/kau.symfony2.com/vendor/symfony/src/Symfony/Component/Form/Util/PropertyPath.php on line 347 and defined in /opt/lampp/htdocs/kau.symfony2.com/src/Acme/TaskBundle/Entity/Task.php line 52"
I searched a lot but could't find the solution.
FilePath: Acme/TaskBundle/Form/Type/TaskType.php
<?php
// src/Acme/TaskBundle/Form/Type/TaskType.php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class TaskType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('task', 'text', array('max_length' => 20));
$builder->add('address', 'textarea', array('required' => true, 'read_only' => false));
$builder->add('dueDate', 'date');
$builder->add('category', new CategoryType());
}
public function getName()
{
return 'task';
}
}
?>
FilePath : Acme/TaskBundle/Resources/Views/Default/new.html.twig
<form action="{{ path('AcmeTaskBundle_newpage') }}" method="post" {{ form_enctype(form) }} novalidate>
{{ form_errors(form) }}
<div>
{{ form_errors(form.task) }}
{{ form_label(form.task, 'Task Description', { 'label_attr': {'class': 'task_field' }}) }}
{{ form_widget(form.task, { 'attr': {'class': 'task_field'} }) }}
</div>
<div>
{{ form_errors(form.address) }}
{{ form_label(form.address) }}
{{ form_widget(form.address) }}
</div>
<div>
{{ form_errors(form.dueDate) }}
{{ form_label(form.dueDate) }}
{{ form_widget(form.dueDate) }}
</div>
<h3>Category</h3>
<div class="category">
{{ form_row(form.category.name) }}
</div>
{{ form_rest(form) }}
<input type="submit" />
</form>
FilePath: Acme/TaskBundle/Form/Type/CategoryType.php
<?php
namespace Acme\TaskBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilder;
class CategoryType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('name','text');
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Acme\TaskBundle\Entity\Category',
));
}
public function getName()
{
return 'category';
}
}
?>
Can u show your code ? Coz that error telling u that u use array - when you should use instance of object of Category
// show /Acme/TaskBundle/Entity/Task.php plz :)
and try to change :
$builder->add('category', new CategoryType());
to
$builder->add('category', 'collection', array('type' => new CategoryType));
Related
Here is the form connected to database
class JsonType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('author')
->add('jsondata')
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => JsonBlog::class,
]);
}
}
and there is HTML
<div>
{{ form_start(form) }}
<div class="form-group">
{{ form_label(form.author) }}
{{ form_widget(form.author, {'attr': {'class':'form-control'}})}}
</div>
<div class="form-group">
{{ form_label(form.jsondata) }}
{{ form_widget(form.jsondata, {'attr': {'class':'form-control', 'id':'body'}})}}
</div>
<div id="editor"></div>
<div class="form-group">
<button class="btn btn-info mt">Submit</button>
</div>
{{ form_end(form) }}
</div>
I added <div id="editor"></div> that is not initialized in Entity Class and database.
I want to pass the value of <div id="editor"></div> to the Controller
function postData() {
editor.save().then((outputData) => {
console.log(outputData);
document.getElementById("body").innerHTML = outputData;
}).catch((error) => {
console.log('Failed: ', error)
});
}
I have tried this using JS function but it does not work.
Take a look at: Symfony Form: unmapped field. As you can't pass a div element in form, you'll transform it to an input which will not be mapped to your entity. Then you can retrieve it value in your Controller.
I am still new to Symfony and Php, so I am using the CheckboxType code from Symfony docs.
Currently no message is appearing if a user attempts to register and the checkbox is unchecked, but it will still prevent the user from making a account.
(1) I would like a error message to appear next to the checkbox in red stating the box must be checked in order to proceed. I would also like to customize this message.
Thank you!
Register.html
{% extends 'base.html.twig' %}
{% block body %}
<div class="container">
<div class="row">
<div class="col-xs-12">
<h1>Register!</h1>
{{ form_start(form) }}
{{ form_row(form.username) }}
{{ form_row(form.email) }}
{{ form_row(form.plainPassword.first, {
'label': 'Password'
}) }}
{{ form_row(form.plainPassword.second, {
'label': 'Repeat Password'
}) }}
Terms of service
{{ form_widget(form.termsAccepted) }}
cancel
<button type="submit" class="btn btn-primary" formnovalidate>
Register
</button>
<br></br>
<p>Privacy Policy
{{ form_end(form) }}
</div>
</div>
</div>
{% endblock %}
RegistrationForm.php
class UserRegistrationForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('email', EmailType::class)
->add('username', TextType::class)
->add('plainPassword', RepeatedType::class, ['type' => PasswordType::class])
->add('termsAccepted', CheckboxType::class, array(
'mapped' => false,
'constraints' => new IsTrue(),));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'validation_groups' => ['Default', 'Registration']
]);
}
}
The problem is that you are using:
{{ form_widget(form.termsAccepted) }}
for rendering the checkbox. This will only render the widget, whereas:
{{ form_row(form.termsAccepted) }}
as is used by all the user fields would contain the label, the widget and the error message. If you want to keep the widget, e.g. because using form_row messes up the template somehow you could render the errors individually using:
{{ form_errors(form.termsAccepted) }}
You might also want to check out the documentation on Form Customization.
i am a newbee in symfony2.
I am working on a searching functionality and here is my code in my indexAction:
/**
* #Route("/admin/users/", name="userspage")
*/
public function indexAction(Request $request)
{
$repo = $this->getDoctrine()->getRepository('AppBundle:User');
$users = $repo->getUsers();
//create
$form = $this->createForm(new SearchType());
if ($form->handleRequest($request)->isSubmitted()) {
if($form->isValid()){
return new Response("Valid");
} else {
return new Response("Not Valid");
}
}
return $this->render('AppBundle:User:index.html.twig', array(
'base_dir' => realpath($this->container->getParameter('kernel.root_dir').'/..'),
'active_nav' => 'users',
'users' => $users,
'form' => $form->createView(),
));
}
Here is my FormType:
class SearchType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
$builder->add('term', 'text' , array('attr'=> array('placeholder'=>
'Enter name to search', 'class' => 'form-control'),
'label' => 'Search: '
));
}
public function getName()
{
return 'user_search';
}
}
Here is how i render the form:
<div class="row row-padding no-gutter">
<form action="{{ path('userspage') }}" method="GET">
<div class="col-lg-1">
{{ form_label(form.term) }}
</div>
<div class="col-lg-4">
{{ form_widget(form.term) }}
</div>
<div class="col-lg-4">
<button type="submit" class="btn btn-default"><i class="fa fa-search"></i> Search</button>
</div>
{{ form_rest(form) }}
</form>
</div>
My problem is, the form never gets valid and never gets submitted. Why is that so?
Thanks.
The method of a form is POST by default. You can use ->setMethod('GET') or add method => 'GET' to the options to make your form use the GET method.
It's also advised to use {{ form_start(form) }} and {{ form_end(form) }} instead of hardcoded html tags, since this will make sure your method is alright.
See http://symfony.com/doc/current/book/forms.html#changing-the-action-and-method-of-a-form for more information.
I got an issue to display a form in popup view. I have read the Symphony documentation and created a bundle to store my form. Then in the base controller I have tried to load it...
I got the following error:
Variable "form" does not exist in nostalgie90sloginUserBundle:Default:loginUser.html.twig at line 1
I want to display this form in a popup using leanModal jquery
The base file where the main view is loaded
base.html.twig:
//some stuff of the base
//....
<div id="loginmodal" style="display:none;">
<p> MON FORMULAIRE </p>
<!--{{ include ("nostalgie90sloginUserBundle:Default:loginUser.html.twig") }} -->
{{ render(controller('nostalgie90sloginUserBundle:Default:new')) }}
</div>
</a>
My controller where the form is loaded:
class DefaultController extends Controller//login bundle
{
public function newAction()
{
$user = new User90s();
$form = $this->createForm(new LoginForm(), $user);
return $this->render('nostalgie90sloginUserBundle:Default:loginUser.html.twig', array('form' => $form->createView(), ));
}
public function indexAction($name)
{
}
}
My form class:
class LoginForm extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('login');
$builder->add('password');
$builder->add('mail');
}
public function getName()
{
return 'login';
}
public function getDefaultOptions(array $options)
{
return array('data_class' => 'nostalgie90s\BaseBundle\Entity\User90s', );
}
}
And finally the view of the form loginUser.html.twig:
{{ form_start(form) }}
{{ form_errors(form) }}
{{ form_row(form.login) }}
{{ form_row(form.password) }}
<input type="submit" />
{{ form_end(form) }}
I'm trying to use twig extensions as widgets to render sections of the page.
I have this class EventWidget, which is a twig extension that defines a twig function called event_widget_create that's responsible for rendering the create page of my entity.
The problem is, There's no form errors printed inside the view, even though there're errors displayed when I do var_dump($form->getErrorsAsString()) inside the controller or the widget function.
There's something that I noticed, when clicking submit, the fields data disappears and I get the feeling that the page reloads.
Here's my widget extension code:
class EventWidget extends \Twig_Extension
{
/**
* #var Twig_Environment
*/
protected $env;
/**
* #var \Tsk\FEBundle\FormHandler\EventFormHandler
*/
protected $eventFormHandler;
function __construct(EventFormHandler $eventFormHandler)
{
$this->eventFormHandler = $eventFormHandler;
}
/**
* #param Twig_Environment $environment
*/
public function initRuntime(Twig_Environment $environment)
{
$this->env = $environment;
}
public function getFunctions()
{
return [
new \Twig_SimpleFunction("event_widget_create", [$this, "getEventWidgetCreate"]),
];
}
public function getEventWidgetCreate(FormInterface $form)
{
return $this->env->render("#Default/Partial/events_widget_create.html.twig",[
"form" => $form->createView()
]);
}
/**
* #return string
*/
public function getName()
{
return "event_widget";
}
}
And here's my controller:
/**
* #Route("/")
*
* #package Tsk\FEBundle\Controller
*/
class EventController extends Controller
{
/**
* #Route("/event/create", name="tsk_fe_event_create")
* #Template("#Default/event_create.html.twig")
* #Security("has_role('ROLE_ARTIST')")
*/
public function createEventAction(Request $request)
{
$handler = $this->get("tsk_fe.event_form.handler");
$form = $handler->create();
if ($request->getMethod() == "POST") {
if ($handler->process($form)) {
return new RedirectResponse($this->generateUrl("tsk_fe_default_index"));
}
}
return ["form" => $form];
}
}
And the form:
class EventType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add("title", "text", [
"error_bubbling" => true
])
->add("description", "textarea", [
"required" => false
])
->add("start", "thrace_datetimepicker", [
"label" => "From",
"error_bubbling" => true
])
->add("end", "thrace_datetimepicker", [
"label" => "To",
"error_bubbling" => true
])
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults([
"data_class" => "Tsk\FEBundle\Entity\Event",
]);
}
public function getName()
{
return "event";
}
}
And lastly the view:
This's the main view:
"#Default/event_create.html.twig"
{% extends "#TskFE/layout.html.twig" %}
{% block content %}
{{ event_widget_create(form)|raw }}
{% endblock content %}
And this's the partial view that's rendered by the widget:
"#Default/Partial/events_widget_create.html.twig":
{% form_theme form with ['ThraceFormBundle:Form:fields.html.twig'] %}
{{ form_start(form, {"action": url("tsk_fe_event_create"), 'attr': {'novalidate': 'novalidate'} }) }}
<div class="form-group">
{{ form_label(form.title) }}
{{ form_widget(form.title, {"attr":{"class": "form-control"} }) }}
{{ form_errors(form.title) }}
</div>
<div class="form-group">
{{ form_label(form.description) }}
{{ form_widget(form.description, {"attr":{"class": "form-control"} }) }}
{{ form_errors(form.description) }}
</div>
<div class="form-group">
{{ form_label(form.start) }}
{{ form_widget(form.start, {"attr":{"class": "form-control"} }) }}
{{ form_errors(form.start) }}
</div>
<div class="form-group">
{{ form_label(form.end) }}
{{ form_widget(form.end, {"attr":{"class": "form-control"} }) }}
{{ form_errors(form.end) }}
</div>
<input type="submit" value="Submit" class="btn btn-info"/>
Cancel
{{ form_rest(form) }}
{{ form_end(form) }}
It seems you have bubbled your errors by using 'error_bubbling' => true. Not sure if it is what you want because you render error individually by field.
Error bubbling means all errors are attached to the parent form instead of being attach to the related field. So, if it is what you want, you must add {{ form_errors(form) }} on top of your form in your template in order to get your errors displayed otherwise, just remove the error_bubbling option.