I'd like access to the instance of the entity when using an EntityType::class. I have a form like below:
->add('fooBars', MyNewType::class, [
'class' => FooBar::class,
'choices' => $fooBars,
'label' => 'Foo Bar',
'multiple' => true,
'expanded' => true,
'required' => false,
'by_reference' => false,
]);
I've created a new type which has the parent of entity type, I then have a custom template as well. Having followed this I have my entity type displaying but where I'm looping over the children, I don't know how to access the entity.
{% block foo_bar_widget %}
{% spaceless %}
{% if expanded %}
<ul {{ block('widget_container_attributes') }}>
{% for child in form if not child.rendered %}
<li>
{{ form_widget(child) }}
{{ form_label(child) }}
</li>
{% endfor %}
</ul>
{% else %}
{{ block('choice_widget') }}
{% endif %}
{% endspaceless %}
{% endblock %}
I'd like to call a method on the entity it's looping over but I'm unsure how to access it. I can't dump child as it produces too much.
This can be achieved using the following:
{% set entity = form.vars.choices[child.vars.value].data %}
So the complete block may look like:
{% block foo_bar_widget %}
{% spaceless %}
{% if expanded %}
<ul {{ block('widget_container_attributes') }}>
{% for child in form if not child.rendered %}
{% set entity = form.vars.choices[child.vars.value].data %}
<li>
{{ form_widget(child) }}
{{ form_label(child) }}
</li>
{% endfor %}
</ul>
{% else %}
{{ block('choice_widget') }}
{% endif %}
{% endspaceless %}
{% endblock %}
And now you can call entity methods like so:
{{ entity.name }}}
Related
i can't find the {% if categoryName %} Code for parent / subcategory.
Please See my Screenshots and Codes:
Actually:
Should be like this:
Backend:
My Shortcode for those Views atm:
[events category="66"]
ShortcodeEvents.php File:
<?php
namespace WpTheme\Shortcodes\Module;
use WpTheme\Shortcodes\ShortcodeModule;
class ShortcodeEvents extends ShortcodeModule
{
/**
* #param $atts
*
* #return mixed
*/
public function handle($atts, $content = null) {
extract(shortcode_atts([
'category' => false,
'limit' => - 1,
'parent' => $sub_category->cat_ID,
], $atts));
$args = [
'posts_per_page' => $limit,
];
if ($category) {
$category = collect(explode(',', $category))->map(function ($value) {
return trim($value);
})->filter()->toArray();
$args = collect($args)->merge([
'tax_query' => [
[
'taxonomy' => 'event-category',
'field' => 'term_id',
'terms' => $category,
],
],
])->toArray();
$events = app(\WpTheme\PostTypes\Repository\Event::class)->all($args);
$categoryName = get_term(array_shift($category), $taxonomy)->name;
} else {
$events = app(\WpTheme\PostTypes\Repository\Event::class)->allGroupedByCategory();
}
return $this->renderView('shortcodes/events.twig', compact('events', 'categoryName'), false);
}
}
My twig File:
{% if events %}
{% if categoryName %}
<h2>{{ categoryName }}</h2>
<hr class="mt-0 mb-8">
{% endif %}
{% for parentTerm in events %}
<div class="{{ loop.index == 1 ? 'mb-default' : 'mt-default' }}">
<div class="mb-8 mb-lg-12 mb-xl-16">
<h2>{{ parentTerm.name }}</h2>
{% if parentTerm.description %}
<p>{{ parentTerm.description }}</p>
{% endif %}
</div>
{% for childTerm in parentTerm.childTerms %}
<div class="mb-8 mb-lg-12">
<h3>{{ childTerm.name }}</h3>
{% for event in childTerm.events %}
{% set index = random() %}
<div class="my-4">
<b-button variant="unstyled" v-b-toggle.accordion-{{ index }} class="accordion-trigger">
<span class="plus"></span>
<h4>{{ event.title }}</h4>
</b-button>
<b-collapse id="accordion-{{ index }}" accordion="my-accordion" role="tabpanel">
<div class="py-4 py-lg-6">
{% set speaker = event.meta('speaker') %}
{% if speaker %}
<p>
{{ speaker.title }}
</p>
{% endif %}
{% if event.meta('dates') %}
<table class="table-responsive-md">
<thead>
<tr>
<th>{{ function('trans', 'global.date') }}</th>
<th>{{ function('trans', 'global.place') }}</th>
<th>{{ function('trans', 'global.topic') }}</th>
</tr>
</thead>
<tbody>
{% for date in event.meta('dates') %}
<tr>
<td class="text-nowrap">{{ date.date|date("d.m.Y") }}</td>
<td class="text-nowrap">{{ date.location }}</td>
<td>{{ date.topic }}</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endif %}
</div>
</b-collapse>
</div>
{% endfor %}
</div>
{% endfor %}
</div>
{% endfor %}
{% endif %}
I found out, that at least i can get some Items from Subcategory if i use:
{{ parentTerm.title }} instead of {{ event.title }}
{% if parentTerm.meta('dates') %} instead of {% if event.meta('dates') %}
But parentTerm.category or parentTerm.categoryName seems not working.
Any Ideas?
#Alorsons I want to make sure you're aware that subcategories/child terms naturally come through any Timber\Term object via {{ term.children }} — this returns an array of other Timber\Term objects representing any children (subcategories for the category taxonomy — but will work with any hierarchical taxonomy)
How can I access a field in collection in twig
$builder
->add('name', 'text', array('required' => false))
->add('email', 'collection', array(
'type' => new UsersEmailAddressesType(),
'allow_add' => true
))
UserEmailAddressesType has two fields name and email, how can I access email field in twig ?
In the symfony cookbook there is an example on how to embed collections in forms. The solution there looks like this (adapted to your form example):
<ul>
{% for email in form.email %}
<li>{{ form_row(email.address) }}</li>
{% endfor %}
</ul>
Since you want to place the inputs next to each other you might want to check whether the loop.index is odd, even or divisibleby() for example like this:
{% for email in form.email %}
{% if loop.index is odd %}
<li class="float-left">
{% else %}
<li class="float-right">
{% endif %}
{{ form_row(email.address) }}</li>
{% endfor %}
It seems that Symfony2 Form component does not handle this common case. Below is what I want in my html
The code looks like :
->add('code', 'choice', array(
'choices' => array(
'Food' => array('pizza', 'burger', 'icecream'),
'Music' => array('poney', 'little', 'pocket'),
),
'multiple' => true,
'expanded' => true,
'required' => true
));
Which gives in reality the wrong output :
It's wierd because the case with expanded => false is correctly handled
How to handle that case please ?
Ok so here's the form_theme solution for this
{% block _user_code_widget %}
<div {{ block('widget_container_attributes') }}>
{% for name, choices in form.vars.choices %}
<ul>
<li class="checkbox_category">
<input type="checkbox" class="checkallsub" /> {{ name }}
</li>
{% for key,choice in choices %}
<li class="indent">
{{ form_widget(form[key]) }}
{{ form_label(form[key]) }}
</li>
{% endfor %}
</ul>
{% endfor %}
</div>
{% endblock %}
Of course the extra js layer is missing, but you get the idea.
I have this form element I want to render without a label, but I can't find the way...
$builder
->add('gender', 'choice', array(
'expanded' => true,
'choices' => array(
'Male' => 'm',
'Female' => 'f',
)
))
;
some help please, this isn't working:
{% block choice_widget %}
{% spaceless %}
{% for child in form %}
<input type="radio" value="{{ child.get('value') }}">
{% endfor %}
{% endspaceless %}
{% endblock choice_widget %}
I'm getting Array to string conversion
What I wanna do is an image based gender selector, just clicking an image to make the selection.
When using the form component, do not ever render form fields yourself, always rely on the form_ helpers as described in the form documentation.
In your case, this should work:
{{ form_label(form.gender) }}
{{ form_errors(form.gender) }}
{% for choiceFormView in form.gender %}
{{ form_widget(choiceFormView) }}
{% endfor %}
So I've an EmailAdmin configuration to manage a NewsletterBundle.
Everything works i've got the edit , list , and show default actions which works.
I looked in Vendor/SonataAdminBundle where was the template to edit/add an entity (with the "create" / "create and add" button) and i found this template : "base_edit_form.html.twig" which contains the buttons.
So i do this :
//Configure a new route to sendemail and add action to configure form fields
namespace Jade\NewsletterBundle\Admin;
use Doctrine\Common\Collections\Collection;
use Sonata\AdminBundle\Route\RouteCollection;
//use Jade\ReveBundle\Entity\Thematique;
use Sonata\AdminBundle\Admin\Admin;
use Sonata\AdminBundle\Datagrid\ListMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Validator\ErrorElement;
use Sonata\AdminBundle\Form\FormMapper;
class EmailAdmin extends Admin
{
protected function configureRoutes(RouteCollection $collection) {
$collection->add('sendemail','/sendemail');
}
protected function configureFormFields(FormMapper $formMapper)
{
$formMapper
->add('objet')
//->add('corps')
->add('corps', null, array('required' => false, 'attr' => array('class' => 'ckeditor')))
->add('groupes')
->add('groupes', 'sonata_type_model',
array(
'by_reference' => false,
'expanded' => true,
'label' => 'Groupes',
'compound' => true,
'multiple' => true,
)
)
->add('_action', 'actions', array( 'actions' => array(
'sendemail' => array('template' =>
'NewsletterBundle:Admin:sendemail.html.twig'),)));
}
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
{
$datagridMapper
->add('objet')
->add('corps')
;
}
protected function configureListFields(ListMapper $listMapper)
{
$listMapper
->addIdentifier('id')
->add('objet')
->add('corps')
;
}
public function validate(ErrorElement $errorElement, $object)
{
$errorElement
->with('objet')
->assertMaxLength(array('limit' => 255))
->end()
;
}
// Here is my EmailAdminBundle :
namespace Jade\NewsletterBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Template;
class EmailAdminController extends Controller
{
/**
* #Route("/sendemail")
* #Template()
*/
public function sendemailAction()
{
return $this->render('NewsletterBundle:Admin:sendemail.html.twig');
}
}
//in NewsletterBundle/Resources/views/Admin/sendemail.html.twig
{% block form %}
Override
{% set url = admin.id(object) ? 'edit' : 'create' %}
{% if not admin.hasRoute(url)%}
<div>
{{ "form_not_available"|trans({}, "SonataAdminBundle") }}
</div>
{% else %}
<form class="form-horizontal" action="{{ admin.generateUrl(url, {'id': admin.id(object), 'uniqid': admin.uniqid, 'subclass': app.request.get('subclass')}) }}" {{ form_enctype(form) }} method="POST">
{% if form.vars.errors|length > 0 %}
<div class="sonata-ba-form-error">
{{ form_errors(form) }}
</div>
{% endif %}
{% block sonata_pre_fieldsets %}{% endblock %}
{% for name, form_group in admin.formgroups %}
<fieldset {% if form_group.collapsed %}class="sonata-ba-fielset-collapsed"{% endif %}>
<legend>
{% if form_group.collapsed %}
{{ name|trans({}, admin.translationdomain) }}
{% else %}
{{ name|trans({}, admin.translationdomain) }}
{% endif %}
</legend>
<div class="sonata-ba-collapsed-fields">
{% for field_name in form_group.fields %}
{% if admin.formfielddescriptions[field_name] is defined %}
{{ form_row(form[field_name])}}
{% endif %}
{% endfor %}
</div>
</fieldset>
{% endfor %}
{% block sonata_post_fieldsets %}{% endblock %}
{{ form_rest(form) }}
{% block formactions %}
<div class="well form-actions">
{% if app.request.isxmlhttprequest %}
{% if admin.id(object) %}
<input type="submit" class="btn btn-primary" name="btn_update" value="{{ 'btn_update'|trans({}, 'SonataAdminBundle') }}"/>
{% else %}
<input type="submit" class="btn" name="btn_create" value="{{ 'btn_create'|trans({}, 'SonataAdminBundle') }}"/>
{% endif %}
{% else %}
{% if admin.supportsPreviewMode %}
<input class="btn btn-info persist-preview" name="btn_preview" type="submit" value="{{ 'btn_preview'|trans({}, 'SonataAdminBundle') }}"/>
{% endif %}
{% if admin.id(object) %}
<input type="submit" class="btn btn-primary" name="btn_update_and_edit" value="{{ 'btn_update_and_edit_again'|trans({}, 'SonataAdminBundle') }}"/>
<input type="submit" class="btn" name="btn_update_and_list" value="{{ 'btn_update_and_return_to_list'|trans({}, 'SonataAdminBundle') }}"/>
{% if admin.hasroute('delete') and admin.isGranted('DELETE', object) %}
{{ 'delete_or'|trans({}, 'SonataAdminBundle') }}
<a class="btn btn-danger" href="{{ admin.generateObjectUrl('delete', object) }}">{{ 'link_delete'|trans({}, 'SonataAdminBundle') }}</a>
{% endif %}
{% else %}
<input class="btn btn-primary" type="submit" name="btn_create_and_edit" value="{{ 'btn_create_and_edit_again'|trans({}, 'SonataAdminBundle') }}"/>
<input class="btn" type="submit" name="btn_create_and_create" value="{{ 'btn_create_and_create_a_new_one'|trans({}, 'SonataAdminBundle') }}"/>
{% endif %}
{% endif %}
</div>
{% endblock formactions %}
</form>
{% endif%}
{% endblock %}
And i've got the error : Could not load type "actions", so i don't know why i've got this error ? And if it's the good way to override a specific view of a specific entity ?
Thank you for your help