I'm working with drupal 8. I enable debug and I found [
<!-- BEGIN OUTPUT from ‘core/themes/stable/templates/dataset/table.html.twig’ --> ] then I overwrite table.html.twig in my theme folder. Now the tag include a link that I want to add [/edit] to it. to make user navigate to the edit page. the following code is from the core file.
<tbody>
{% for row in rows %}
<tr{{ row.attributes }}>
{% for cell in row.cells %}
<{{ cell.tag }}{{ cell.attributes }}>
{{- cell.content -}}
</{{ cell.tag }}>
{% endfor %}
</tr>
{% endfor %}
</tbody>
I try to create preprocess function
/* this preprocess method is to add variables to table.html.twig*/
function mytheme_preprocess_table(&$variables) {
print_r(array_keys($variables));
$variables['output'] = "add your custom";
$variables['hello'] = 'world';
}
but I don't know how to access [cell.content] in order to add [/edit]
How is the table generated? it's from the code. Where is the table displayed? in https://example.com/ar/webform/companies_form/submissions/ What is the path of "edit web form page"? webform/companies_form/submissions/3119/edit Have you debugged the template to see what variables are available in the template? yes,
Array
(
[0] => header
[1] => rows
[2] => attributes
[3] => sticky
[4] => responsive
[5] => empty
[6] => footer
[7] => caption
[8] => colgroups
[9] => theme_hook_original
[10] => title_attributes
[11] => content_attributes
[12] => title_prefix
[13] => title_suffix
[14] => db_is_active
[15] => is_admin
[16] => logged_in
[17] => user
[18] => directory
[19] => header_columns
[20] => no_striping
[21] => #cache
)
Related
I've used a custom template no problem when using a collection of checkboxes to change the html to be in a table like this:
{% form_theme form _self %}
{% block _packing_dispatch_form_group_formsA_0_packagingList_widget %}
<div {{ block('widget_container_attributes') }}>
<div class="table-responsive">
<table>
{%- for child in form %}
<tr>
<td class="firstCol">{{- form_label(child, null, {translation_domain: choice_translation_domain}) -}}</td>
<td>{{- form_widget(child) -}}</td>
</tr>
{% endfor -%}
</table>
</div>
</div>
{% endblock %}
But now the collection has changed so it holds a collection of another form type which then holds the checkboxes, i can't figure out how i now apply the same template to the new collection of the second form type.
Here is the code:
PackagingDispatchFormGroupType.php
$data= [];
$packingForm = new PackingDispatchForm();
$data[] = $packingForm;
$builder->add('formsA', CollectionType::class,[
'entry_type'=>PackingDispatchFormType::class,
'entry_options'=>[
'user'=>$this->user
],
'allow_add'=>true,
'allow_delete'=>true,
'data'=>$data,
'mapped'=>false
]);
PackagingDispatchFormType.php
->add('packagingList',ChoiceType::class,[
'multiple'=>true,
'expanded'=>true,
'attr'=>[
'class'=>'packagingListInput'
],
'choices'=>[
'Digitherm Camera, CDX8950-400' => 'Digitherm Camera, CDX8950-400',
'Battery, CDX370PACK' => 'Battery, CDX370PACK',
'Battery Tab, CDX8950-514' => 'Battery Tab, CDX8950-514',
'Memory Card, CDX8IS' => 'Memory Card, CDX8IS',
'Memory Card Reader, CDXUSBR' => 'Memory Card Reader, CDXUSBR',
'Charging Station, CDX370D' => 'Charging Station, CDX370D',
'Power Supply (3x Adapters), CDX370C' => 'Power Supply (3x Adapters), CDX370C',
'Australian Adapter' => 'Australian Adapter',
'Access Key, XP-100' => 'Access Key, XP-100',
'Wrist Strap, CDX8950-550' => 'Wrist Strap, CDX8950-550',
'Fragrance Card, CDX8950-512' => 'Fragrance Card, CDX8950-512',
'Accessory Card' => 'Accessory Card',
'Instructions For Safe User, CDX8950-511 Rev. A' => 'Instructions For Safe User, CDX8950-511 Rev. A',
'User Manual, CDX8950-507, Rev. A' => 'User Manual, CDX8950-507, Rev. A',
'Battery Warning Card' => 'Battery Warning Card',
'Charger Instruction Leaflet' => 'Charger Instruction Leaflet',
'Declaration Of Conformity, SOM15, Rev. A' => 'Declaration Of Conformity, SOM15, Rev. A'
],
'disabled'=>($this->forView ? true : false),
'choice_attr'=>function($choice, $key, $value){
return ['required'=>true];
},
'invalid_message'=>'All Of The Packaging List Checkboxes Are Required'
]);
The whole point here is that i can now duplicate the form field as an array of the checkboxes, but can't seem to apply the same html template.
In the list view, when I first click in the sort button, the default direction is ASC for all the fields. Is there any way to set the direction for each field? Something like:
$listMapper
->add('name', null, [
'sort_order' => 'ASC'
])
->add('date', null, [
'sort_order' => 'DESC'
])
Well, I managed to make it work although it's not very fancy. In the SonataAdminBundle/views/CRUD/base_list.html.twig template, right after the sort parameters are created
{% set sort_parameters = admin.modelmanager.sortparameters(field_description, admin.datagrid) %}
I added this code:
{% set sortFilters = sort_parameters['filter'] %}
{% set sortFilters = sortFilters|merge({'_sort_order': field_description.options._sort_order}) %}
{% set sort_parameters = sort_parameters|merge({'filter': sortFilters}) %}
now the only thing I have to do is tell the field in the Admin the sort_order, like this:
$listMapper->
->add('sent', null, [
'_sort_order' => 'DESC',
...
there is no need to put ASC, since it's the default value.
As I said before: not fancy nor I like it very much, but it works for me.
I have a many to many entity relationship, User and Project
The User entity has only one field, the id field since it is extending the FOsUserBundle. I understand that to access the current logged in users by calling the container
$user = $this->container->get('security.context')->getToken()->getUser();
But that's not the case.A project has many users saved in a database.Now I can access it by using a twig loop
users_projects//a many to many table
project_id user_id
3 1
3 2
<td>{% for user in project.users %}{{ user.id}}{% endfor %}</td>
outputs 1,2
The user entity has no getUsername method as it has only one id field.How would you display the username instead of an i.d?
Update
Already solved this.I dont really sure if its the proper way .In ProjectType, I added this
->add('users', 'entity', array(
'class' => 'UserBundle:User',
'query_builder' => function (EntityRepository $er) {
return $er->createQueryBuilder('u')
->orderBy('u.username', 'ASC');
},
'expanded' => true,
'multiple' => true
))
With this set up
<td>
{% for user in entity.users %}
{{ user.username }}
{% if not loop.last %},{% endif %}
{% endfor %}
</td>
Now works.Just don't forget to include
use Doctrine\ORM\EntityRepository;
In FormType, else it will throw an error something like
Catchable Fatal Error: Argument 1 passed to.....must be an instance of \EmployeeBundle\Form\EntityRepository, instance of Doctrine\ORM\EntityRepository given
I want to add a class to the <a>-Tag of a Field that consists of a URL-link and a link text (it's a field of type "Link") and the name of the field is content.field_c_button_link
So with twig in my HTML-File I want to have something like this:
{{ content.field_c_button_link.0.addClass('button blue') }}
How can I add a class properly?
Why not piece the anchor tag together manually? That way you have complete control over everything. Something like this in your template
{{content.field_url.0['#title']}}
Ok, this is horrible but it's the only way I found to get this to work:
If you look at the default drupal build array for your link you should see that content.field_c_button_link.0 is an array(4)
'#type' => string(4) "link"
'#title' => string(15) "Big Blue Button"
'#options' => array(0)
'#url' => object Drupal\Core\Url(11)
So, to set classes directly on the <a> tag we have to load '#options' (which is presently empty) with the right setup of subarrays
'#options' => array(1)
'attributes' => array(1)
'class' => array(2)
string(6) "button"
string(4) "blue"
The only way I could find to do this within twig was to use a series of temps and merging them with the original array because twig wouldn't parse anything else I tried:
{% set temp = {'attributes': {'class': ['button','blue']}} %}
{% set temp2 = content.field_c_button_link.0 %}
{% set temp2 = temp2|merge({'#options': temp}) %}
{% set temp3 = content.field_c_button_link|without('0') %}
{% set temp3 = temp3|merge({'0': temp2}) %}
{% set content = content|merge({'field_c_button_link': temp3}) %}
Note the |without which is a Drupal/twig filter. I had to use it to remove the empty '0' element to avoid having the link print twice.
Please tell me there is an easier way.
I have 2 entities: Projects and Categories. I have a ManyToMany relation between these two.
The Categories has ManytoOne relation with the entity "industry"
At this moment, there is no direct relation between Projects and industry and I would like to keep this like so, for further search functionality. So in the category table, the list includes categories from all industries.
When I build the form to edit the project (using the form widget), I have a list of checkboxes representing all the categories listed in my category table.
I would like to group the category choices by industry. How can this be done on the form layout only? How can I extract the industry value from the twig widget form data and group the checkboxes by the industry entity?
Thanks Leevi,
I could not find how to implement the suggestion above using both industry and category related entities... I finally found this way of going around the issue, tell me if there is a simpler way, but this works perfect now.
This is my form in the controller
$form = $this->createFormBuilder($project)
->add('categories', 'entity', array(
'class' => 'ACMEProjectBundle:Category',
'property' => 'name',
'expanded' => true,
'multiple' => true,
->getForm();
I also pass to the rendered form the array of industries which has each a list of related categories
$industries = $this->getDoctrine()->getManager()->getRepository('ACMEProjectBundle:Industry')->findall();
In the form.html.twig template
{{ form_errors(form) }}
<form method="post" {{ form_enctype(form) }}>
{% for industry in industries %}
<h4>{{industry.name}}</h4>
<ul class="unstyled">
{% for category in industry.categories %}
{% set key = category.id %}
<li>{{ form_widget(form.categories[key]) }}{{category.name}}</li>
{% endfor %}
</ul>
{% endfor %}
{{form_rest(form)}}
Which gives me the wanted results.
Hopefully this will be enough direction without giving you exact code examples :).
You'll have to setup your form with an expanded, multiple, entity field like so:
<?php
// src/Acme/ProjectBundle/Controller/DefaultController.php
namespace Acme\ProjectBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Acme\ProjectBundle\Entity\Project;
use Symfony\Component\HttpFoundation\Request;
class DefaultController extends Controller
{
public function newAction(Request $request)
{
// create a project and give it some dummy data for this example
$project = new Project();
$form = $this->createFormBuilder($project)
->add('categories', 'entity', array(
'expanded' => true,
'multiple' => true,
'group_by' => 'industry.title'
))
->add('save', 'submit')
->getForm();
return $this->render('AcmeProjectBundle:Default:new.html.twig', array(
'form' => $form->createView(),
));
}
}
The group_by parameter groups the options based on the property path:
See: http://symfony.com/doc/current/reference/forms/types/entity.html#group-by
Now group_by renders a select tag but you should be able to override that with a custom twig theme or manually in the template.
Given the form above you can access the choices in {{ form.categories.vars.choices }} and iterate over them manually.
See: {% block choice_widget_collapsed %} in form_div_layout.html.twig to see how the select box is rendered.
Here's some more information of form theming: http://symfony.com/doc/current/cookbook/form/form_customization.html