New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add form elements to batch / list templates for batch action usage #2336

Closed
webdevilopers opened this Issue Aug 22, 2014 · 2 comments

Comments

Projects
None yet
1 participant
@webdevilopers
Contributor

webdevilopers commented Aug 22, 2014

I have a list of PriceQuotes belonging to a Partner. The Superadmin can (re-)assign them to other Partners.

My first attempt is following the docs at:
http://sonata-project.org/bundles/admin/master/doc/reference/batch_actions.html#optional-overriding-the-batch-selection-template

# list__batch.html.twig
{% extends admin.getTemplate('base_list_field') %}

{% block field %}
    <input type="checkbox" name="idx[{{ admin.id(object) }}]" value="{{ admin.id(object) }}" />

    <select name="partner[{{ admin.id(object) }}]" style="width: auto; height: auto" class="form-control">
        <option value="1">Admin Partner</option>
    </select>
{% endblock %}

I added the {{ admin.id(object) }} as index of the form element to get the correct partner value for each object.

This is supposed to work. But I would prefer a solution where the partner select is shown in the footer near the batch actions select.

For this use case I override the list view in my CRUDController:

# base_list.html.twig l. 118 ff.
{% block batch_actions %}
    <label class="checkbox" for="{{ admin.uniqid }}_all_elements">
        <input type="checkbox" name="all_elements" id="{{ admin.uniqid }}_all_elements">
        {{ 'all_elements'|trans({}, 'SonataAdminBundle') }}
         ({{ admin.datagrid.pager.nbresults }})
    </label>

    <select name="action" style="width: auto; height: auto" class="form-control">
        {% for action, options in batchactions %}
            <option value="{{ action }}">{{ options.label }}</option>
        {% endfor %}
    </select>

    <select name="partner" style="width: auto; height: auto" class="form-control">
        <option value="1">Admin Partner</option>
    </select>
{% endblock %}

This should work too.

My question is how to add the choices / options or complete form elements to the templates.

I tried adding an element inside my CRUDController listAction() method:

    public function listAction()
    {
        if (false === $this->admin->isGranted('LIST')) {
            throw new AccessDeniedException();
        }
        $datagrid = $this->admin->getDatagrid();
        $form = $datagrid->getForm();

        $form->add('partner', 'entity', array(
            'class' => 'SpsBaseBundle:Partner',
            'property' => 'username'
        ));
        ...
    }

But it gives me an error:
You cannot add children to a submitted form

Is there a practical way without implementing my own form using the existing resources - e.g. an eventListener?

@webdevilopers

This comment has been minimized.

Contributor

webdevilopers commented Aug 24, 2014

I just recognized that overriding the base_list.html.twig is global, not per admin class. So I need a way to change the template for each admin class.

In addition to my use case I found another workaround based on the list view inline editing.
Unfortunately editing an entity is not implemented yet:

@webdevilopers

This comment has been minimized.

Contributor

webdevilopers commented Sep 8, 2014

This is the solution I came up with for a different use case but the idea is the same:

Override admin class related list template only inside my admin class:

    public function getTemplate($name)
    {
        switch ($name) {
            case 'list':
                return 'MyBundle:MyAdmin:list.html.twig';
                break;

            default:
                return parent::getTemplate($name);
                break;
        }
    }

Override the CRUDController as mentioned above and edit the listAction:

    public function listAction()
    {
        if (false === $this->admin->isGranted('LIST')) {
            throw new AccessDeniedException();
        }

        $datagrid = $this->admin->getDatagrid();
        $formView = $datagrid->getForm()->createView();

        $actionForm = $this->get('form.factory')->createNamedBuilder('', 'form')
            ->add('testedAt', 'sonata_type_date_picker', array('label' => 'at'))
            ->getForm();

        // set the theme for the current Admin Form
        $this->get('twig')->getExtension('form')->renderer->setTheme($formView, $this->admin->getFilterTheme());

        return $this->render($this->admin->getTemplate('list'), array(
            'action'     => 'list',
            'form'       => $formView,
            'actionForm' => $actionForm->createView(),
            'datagrid'   => $datagrid,
            'csrf_token' => $this->getCsrfToken('sonata.batch'),
        ));
    }

Add my custom form to the batch_actions block of my custom list template:

{% extends 'SonataAdminBundle:CRUD:base_list.html.twig' %}

{% block batch_actions %}
    <label class="checkbox" for="{{ admin.uniqid }}_all_elements">
        <input type="checkbox" name="all_elements" id="{{ admin.uniqid }}_all_elements">
        {{ 'all_elements'|trans({}, 'SonataAdminBundle') }}
         ({{ admin.datagrid.pager.nbresults }})
    </label>

    {{ form_label(actionForm.testedAt) }} {{ form_widget(actionForm.testedAt) }}

    <select name="action" style="width: auto; height: auto" class="form-control">
        {% for action, options in batchactions %}
            <option value="{{ action }}">{{ options.label }}</option>
        {% endfor %}
    </select>
{% endblock %}

This will render the following datepicker:

<label class=" control-label required" for="testedAt"> at </label>
<div class="form-group">
<div id="testedAt" class="input-group date" data-date-format="YYYY-MM-DD">
<input id="testedAt" class=" not-removable" type="text" required="required" name="testedAt">
<span class="input-group-addon">
<span class="glyphicon-calendar glyphicon"></span>
</span>
</div>
</div>
<script type="text/javascript">
jQuery(function ($) {
$('#testedAt').datetimepicker({"pickTime":false,"useCurrent":true,"minDate":"1\/1\/1900","maxDate":"","showToday":true,"language":"en","defaultDate":"","disabledDates":[],"enabledDates":[],"icons":{"time":"glyphicon glyphicon-time","date":"glyphicon glyphicon-calendar","up":"glyphicon glyphicon-chevron-up","down":"glyphicon glyphicon-chevron-down"},"useStrict":false,"sideBySide":false,"daysOfWeekDisabled":[]});
});
</script>

Blogged here:
http://blog.webdevilopers.net/override-crudcontroller-to-add-custom-form-elements-to-list-template-for-batch-action-usage-in-sonataadminbundle/

I will adapt this solution for my first mentioned use case and re-open this issue if it technically doesn't work out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment