I have on my form template new.html.twig a select where all the elements of an entity are loaded ($categories).
Controller
public function newAction(Request $request){
$entity = new Playlist();
$form = $this->createCreateForm($entity);
$em = $this->getDoctrine()->getManager();
$categories = $em->getRepository('PublicartelAppBundle:Category')->getAllCategories();**
return $this->render('PublicartelAppBundle:Playlist:new.html.twig', array(
'categories' => $categories,
'entity' => $entity,
'form' => $form->createView(),
));
}
Select filter that serves to make a search.
Select in my twig template that displays all categories obtained from the query.
new.html.twig
<div class="form-group">
<label for="publicartel_appbundle_category_name">Search for category: </label>
<select id='selectCategory' class="form-control select2">
{% for category in categories %}
<option>
{{ category.name }}
</option>
{% endfor %}
</select>
</div>
JS in my twig template that detects changes in select option to make a new query and retrieve records from the selected option.
JS code
$('#selectCategory').on('change', function () {
var optionSelect = $(this).val();
$.post("{{path('playlist_category') }}", {category: optionSelect},
function (filterContent) {
for (var content in filterContent.category_result) {
for (var name in filterContent.category_result[content]) {
var result = filterContent.category_result[content][name];
console.log(result);
$('#playlist_content_name').append('<option>' + result + '</option>');
}
}
}, 'json');
});
The result of the new query is done in the playlist_category route is assigned to another select this in my twig template with the append method.
<div class="form-group">
<label for="publicartel_appbundle_area_name">Content</label>
{{ form_widget(form.items.vars.prototype.content, { 'id': 'playlist_content_name', 'full_name': '', required: false, 'attr': {'class': 'form-control select2'}}) }}
</div>
This select load other options, but the other select is used to filter options to prevent all options be loaded.
My problem is that when I try to send the form with any of the options obtained from the search, I get an error that the variable categories does not exist in my template twig new.html.twig.
Then, as the method createAction, also conducts a rendering of the template new.html.twig also add the variable $ categories there.
Controller
public function createAction(Request $request){
$entity = new Playlist();
$form = $this->createCreateForm($entity);
$form->handleRequest($request);
$em = $this->getDoctrine()->getManager();
if ($form->isValid()) {
// $em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('playlist_show', array(
'id' => $entity->getId())));
}
$categories = $em->getRepository('PublicartelAppBundle:Category')->getAllCategories();
return $this->render('PublicartelAppBundle:Playlist:new.html.twig', array(
'categories' => $categories,
'entity' => $entity,
'form' => $form->createView(),
));
}
But when complete the form, having chosen an option of select which return the search, instead of addressing the playlist_show route, directs me to the path /create with the form new.html.twig.
Related
I followed this tutorial to add a captcha to my form.
First I install it using
composer require captcha-com/symfony-captcha-bundle:"4.*"
After I Install it, I got an error on a file called captcha.html.twig
Error:
captcha Unexpected "spaceless" tag (expecting closing tag for the
"block" tag defined near line 2).
So I changed {% spaceless %} to {% apply spaceless %}
And the error is gone.
But My captcha bot always returns True (even when I don't even fill it.
Here is the ->add() function of my form:
->add('captchaCode', CaptchaType::class, [
'captchaConfig' => 'ExampleCaptchaUserRegistration',
'constraints' => [
new ValidCaptcha([
'message' => 'Invalid captcha, please try again',
]),
],]);
Code of Routes.yaml :
captcha_routing:
resource: "#CaptchaBundle/Resources/config/routing.yml"
Code of captcha.php :
<?php
// app/config/packages/captcha.php
if (!class_exists('CaptchaConfiguration')) { return; }
// BotDetect PHP Captcha configuration options
return [
// Captcha configuration for example form
'ExampleCaptchaUserRegistration' => [
'UserInputID' => 'captchaCode',
'ImageWidth' => 250,
'ImageHeight' => 50,
],
];
Captcha field on the User.php entity:
protected $captchaCode;
public function getCaptchaCode()
{
return $this->captchaCode;
}
public function setCaptchaCode($captchaCode)
{
$this->captchaCode = $captchaCode;
}
Code in the View (twig)
<span class="txt1 p-b-11">
Are You a Robot?
</span>
<div class="wrap-input100 m-b-36">
{{ form_widget(form.captchaCode, {'attr': {'class': 'input100'} }) }}
<span class="focus-input100"></span>
</div>
<div class="error">{{ form_errors(form.captchaCode) }} </div>
Controlleur function:
/**
* #Route("/register", name="user_register", methods={"GET","POST"})
*/
public function register(Request $request,UserPasswordEncoderInterface $encoder): Response
{
$user = new User();
$form = $this->createForm(UserType::class, $user, ['validation_groups' => ['register'], ]);
$form ->remove("description");
$form ->remove("phone");
$form ->remove("website");
$form ->remove("facebook");
$form ->remove("picture");
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$hash = $encoder->encodePassword($user,$user->getPassword());
$user->setPassword($hash);
// defaults values (user can edit them later)
$user->setDescription("Apparently, this User prefers to keep an air of mystery about them.");
$user->setPhone(null);
$user->setPicture("default.png");
$user->setWebsite(null);
$user->setFacebook(null);
$user->setRoles(["ROLE_USER"]);
// end default values
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
return $this->redirectToRoute('user_login');
}
return $this->render('authentication/register.html.twig', [
'user' => $user,
'form' => $form->createView(),
]);
}
I want to add a dropdow field for category in my form in symfony version 3, I have tried to solutions but each one have their own problem
First got all categories and pass them to my view and show them:
Action:
/**
* Creates a new News entity.
*
* #Route("/new", name="news_new")
* #Method({"GET", "POST"})
*/
public function newAction(Request $request)
{
$news = new News();
$form = $this->createForm('AppBundle\Form\NewsType', $news);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($news);
$em->flush();
return $this->redirectToRoute('news_show', array('id' => $news->getId()));
}
$em = $this->getDoctrine()->getManager();
$categories = $em->getRepository('AppBundle:Category')->findAll();
return $this->render('news/new.html.twig', array(
'news' => $news,
'form' => $form->createView(),
'categories' => $categories,
));
}
View:
{% extends 'base.html.twig' %}
{% block body %}
<h1>News creation</h1>
{{ form_start(form) }}
<label for="news_content" class="required">Category</label>
<select name="news[categoryId]">
{% for category in categories %}
<option value="{{ category.id }}">{{ category.title }}</option>
{% endfor %}
</select>
{{ form_widget(form) }}
<input class="btn btn-sm btn-success" type="submit" value="Create" />
{{ form_end(form) }}
<ul>
<li>
<a class="label label-sm label-info" href="{{ path('news_index') }}">Back to the list</a>
</li>
</ul>
{% endblock %}
The form is created as I expected but when i want to submit it, it show an validation error as bellow:
This form should not contain extra fields.
second solution that I have tried is to generate the dropdown from my Type, so in NewsType I changed the buildForm function as bellow:
/**
* #param FormBuilderInterface $builder
* #param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('categoryId', EntityType::class, [
'class' => 'AppBundle:Category',
'choice_label' => 'title',
])
->add('title')
->add('content')
;
}
It this way, the form also have been created nicely but after submit, an database exception returned and said:
An exception occurred while executing 'INSERT INTO news (category_id, title, content) VALUES (?, ?, ?)' with params [{}, "asdf", "asdf"]:
Catchable Fatal Error: Object of class AppBundle\Entity\Category could not be converted to string
It mean that my category_id passed as an object !
What should I do?
BTW, my english is a little weak, please do not put and minus on my post, I had been ban multiple times.
Thanks in advance.
all symfony is trying to do is to find a string representation of the Category object, so it can populate the option fields.
you can solve this in a couple of ways:
In the Category object, you can make a __toString method.
public function __toString() {
return $this->name; // or whatever field you want displayed
}
or
you can tell symfony which field to use as the label for the field. From docs
$builder->add('attending', ChoiceType::class, array(
'choices' => array(
new Status(Status::YES),
new Status(Status::NO),
new Status(Status::MAYBE),
),
'choice_label' => 'displayName', // <-- where this is getDisplayName() on the object.
));
I am working with Symfony2 and I am trying to create new entity Collection without page reload. My controller works fine, but I have issues with Ajax, I am NOT well familiar with it. Below is the code I already have. When I press submit button, new entity is saved in db, but entity doesn't appear on page.
CollectionController
/**
* #Route("/create-collection", name="collection_create_collection")
* #Template()
*/
public function createAction(Request $request)
{
$collection = new Collection();
$form = $this->createForm(
new CollectionType(),
$collection,
array('method' => 'POST',
'action' => $this->generateUrl('collection_create_submit'),
)
);
return array('collection'=>$collection, 'form' => $form->createView());
}
/**
* #Route("/collection_create_submit", name="collection_create_submit")
*/
public function createSubmitAction(Request $request)
{
$collection = new Collection();
$user = $this->getUser();
$form = $this->createForm(
new CollectionType(),
$collection,
array('method' => 'POST',
)
);
$form->handleRequest($request);
if ($form->isValid() && $form->isSubmitted()) {
$colname = $form["name"]->getData();
$existing = $this->getDoctrine()->getRepository('CollectionBundle:Collection')->findBy(['name' => $colname, 'user' => $user]);
if ($existing) {
return new JsonResponse(['error' => 'Collection with such name already exists']);
}
$em = $this->getDoctrine()->getManager();
$em->persist($collection);
$em->flush();
return new JsonResponse(array(
'success' => $collection
));
}
}
create.html.twig
{% include 'CollectionBundle:Collection:collectionJS.html.twig' %}
<div class="collection-create">
<h3 id="create-collection">Create a collection</h3>
<a class="close-reveal-modal" aria-label="Close">×</a>
{{ form_start(form, {'attr' : {'action' : 'collection_create_collection', 'id': 'create-collection-form'}}) }}
{{ form_widget(form) }}
<a class="button custom-close-reveal-modal" aria-label="Close">Cancel</a>
<button type="submit" value="create" class="right" onclick="createCollection();">Create</button>
{{ form_end(form) }}
</div>
<script type="application/javascript">
$('a.custom-close-reveal-modal').on('click', function(){
$('#externalModal').foundation('reveal', 'close');
});
</script>
collectionJS.html.twig
function createCollection(){
var $form = $('#create-collection-form');
$($form).submit(function(e) {
e.preventDefault();
$.ajax({
type: "POST",
url: $form.attr('action'),
data: $form.serialize()
}).done(function( data ) {
if(data.error)
{
console.log(data.error);
} else if(data.success) {
var collection = data.success;
$('.griditems').prepend('<p>' + collection + '</p>');
$('#externalModal').foundation('reveal', 'close');
}
});
});
}
UPD
The submit is triggered, but now I get undefined instead of entity. Probably, I am sending wrong json response.
UPD
I tried to encode collection entity.
In createSubmitAction I changed return to
$jsonCollection = new JsonEncoder();
$jsonCollection->encode($collection, $format = 'json');
return new JsonResponse(array(
'success' => $jsonCollection
));
How do I get this response in Ajax?
JsonResponse cannot transform your entities into JSON. You need to use a serializer library like JMSSerializerBundle or implement a serializing-method inside your entity.
Check the answers provided here.
How to encode Doctrine entities to JSON in Symfony 2.0 AJAX application?
You have to return a simple $collection object as the standard doctrine entity objects are too large in size. What I recommend is:
return new JsonResponse(array(
'success' => $collection->toArray()
));
and adding a new method to your entity class:
public function toArray(){
return array(
'id' =>$this->getId(),
'name'=>$this->getName(),
// ... and whatever more properties you need
); }
this question may sound a bit newbie. What I am trying to do is to show a form inside a view, create an object and submit it.
My list view shows a list of existing objects and I showed a new/create button that brings the form which creates a new object calling the controller.
I don't know if there is a more proper way to do this but I came up with this code that works partially. The code works when my url is /new (showing only the form), however while it is /list it doesn't work.
List view (only relevant code):
{# AppBundle/Resources/views/list.html.twig #}
<div id="info">
<button type="button" onClick="new()">New Object</button>
</div>
<script>
function new() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
document.getElementById("info").innerHTML = xhttp.responseText;
}
}
xhttp.open("GET", "/new", true);
xhttp.send();
}
</script>
New view:
{# AppBundle/Resources/views/new.html.twig #}
{{ form(form) }}
Controller methods:
// AppBundle/Controller/ObjectController
public function newAction(Request $request)
{
$object = new Object();
$form = $this->createFormBuilder($object)
->add('Text', 'textarea')
->add('save', 'submit')
->getForm();
$form->handleRequest($object);
if ($form->isValid()) {
$em = $this->getDoctrine()->getManager();
$em->persist($object);
$em->flush();
return $this->redirectToRoute('list');
}
return $this->render('AppBundle:new.html.twig', array(
'form' => $form->createView(),
));
}
public function listAction(Request $request)
{
$objects = $this->getDoctrine()
->getRepository('AppBundle\Entity\Object')
->findAll();
return $this->render('AppBundle:list.html.twig', array(
'objects' => $objects,
));
}
Thanks a lot for your time!!
No data are displayed in list.html.twig. You have to add this kind of code:
/.../
{% for object in objects %}
{{ object.text }}
{% endfor %}
<div id="info">
<button type="button" onClick="new()">New Object</button>
</div>
I can't retrieve data from my form, I tried differents ways but no result. My repository :
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('min_price', 'text', array('mapped' => false, 'label' => 'De la :', 'attr'=>
array(
'placeholder'=>'Pretul minim',
'class'=>'form-control')))
->add('max_price', 'text', array('mapped' => false, 'label' => 'Pina la :' , 'attr'=>
array(
'placeholder'=>'Pretul maxim',
'class'=>'form-control')))
)
;
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
parent::setDefaultOptions($resolver);
$resolver->setDefaults(array(
// avoid to pass the csrf token in the url (but it's not protected anymore)
'csrf_protection' => false,
));
}
public function getName()
{
return '';
}
My controller :
public function showCategoryAction($id, $page, Request $request){
$em = $this->getDoctrine()->getManager();
$repositoryProduct = $em->getRepository('ShopDesktopBundle:Product');
$category = $em->getRepository('ShopDesktopBundle:Category')->findOneById($id);
if (!$category) {
throw $this->createNotFoundException('Category not found.');
}
$aFilter = array();
$entity = new Product();
$form = $this->createForm(new ProductType(), $entity,array(
'action' => $this->generateUrl('show_product_category',array("id" => $id, "name" => $category->getCategoryLink(), "page" => $page )), //Your url to generate
'method' => 'GET'
));
$form->handleRequest($request);
$aFilter['iMinPrice'] = $form["min_price"]->getData();
$aFilter['iMaxPrice'] = $form["max_price"]->getData();
print_r($aFilter);
//Searchs products
$aProducts = $repositoryProduct->getProductsOrderByDateDesc($id,null,$aFilter);
if (!$aProducts) {
throw $this->createNotFoundException('Products not found.');
}
//Create pagination
$paginator = $this->get('knp_paginator');
$pagination = $paginator->paginate(
$aProducts,
$page,
3
);
//Send data to view
return $this->render('ShopDesktopBundle:Category:category.html.twig',array(
'category' => $category,
'pagination' => $pagination,
'form' => $form->createView()
));
}
My view :
<form action="{{ path('show_product_category',{ 'id':category.getId(), 'name':category.getCategoryLink() }) }}" method="get" {{ form_enctype(form) }}>
<div class="accordion-group">
<div class="accordion-heading">
<a class="accordion-toggle" data-toggle="collapse" data-parent="" href="#toggleOne">
<em class="icon-minus icon-fixed-width"></em>Pret
</a>
</div>
<div id="toggleOne" class="accordion-body collapse in">
<div class="accordion-inner">
{{ form_widget(form) }}
</div>
</div>
</div>
<input type="submit" class="btn btn-primary marg-left-20" value="Cautare"/>
</form>
The view :
show_product_category:
path: /{id}/{name}/{page}
defaults: { _controller: ShopDesktopBundle:Category:showCategory, page: 1}
requirements:
id: \d+
page: \d+
_method: GET|POST
So the problem is that I can't retrieve data from thi form. For all situations $aFilter is empty. If for example I put in the view in form POST method the filter is with data from form. My url look like this :
?min_price=10&max_price=50.
Help me please. Thx in advance.Exist a solution??
I would not set the form method as GET, just do not specify a method and it will default to POST, which is the usual way to submit a form.
Then handle the form submission in your Controller when the method is POST - like this:
if ($request->isMethod('POST')) {
$form->handleRequest($request);
if ($form->isValid() {
$aFilter['iMinPrice'] = $form->get('min_price')->getData();
$aFilter['iMaxPrice'] = $form->get('max_price')->getData();
}
}
More information on how to handle form submissions in Symfony2 here.
If you really need the form method to be GET, you should be able to get the query string parameters from the request:
$aFilter['iMinPrice'] = $request->query->get('min_price');
$aFilter['iMaxPrice'] = $request->query->get('max_price');