SonataAdminBundle embebed form validation error

梦想的初衷 提交于 2019-12-12 04:15:55

问题


I have an admin class, which included another admin class.

  • Symfony 2.7.9
  • Sonata Admin Bundle 2.3.7

I have it structured in tabs, and the problem is that when there is a validation error in any of the fields of the embedded form is not marked in any way the tab where it is located.

This is my example code: Entity Products.php

<?php

namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Products
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Entity\ProductsRepository")
 */
class Products
{

    //...

    /**
     * 
     * @ORM\OneToMany(targetEntity="Modules", mappedBy="products", cascade={"persist"}, orphanRemoval=true)
     * @ORM\OrderBy({"position" = "ASC"})
     */
    protected $module;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->module= new ArrayCollection();
    }

    //...

    /**
     * Set module
     *
     * @param Doctrine\ORM\PersistentCollection $module
     * 
     */
    public function setModule(\Doctrine\ORM\PersistentCollection $module) {

        if (count($module) > 0) {
            foreach ($module as $m) {
                $this->addModule($m);
            }
        }

        return $this;
    }

    /**
     * Remove module
     *
     * @param \AppBundle\Entity\Modules $module
     */
    public function removeModule(\AppBundle\Entity\Modules $module)
    {
        foreach ($this->module as $k => $s) {
            if ($s->getId() == $module->getId()) {
                unset($this->module[$k]);
            }
        }

    }

    /**
     * Get module
     *
     * @return \Doctrine\Common\Collections\Collection 
     */
    public function getModule()
    {
        return $this->module;
    }


    /**
     * Add module
     *
     * @param \AppBundle\Entity\Modules $module
     * @return Products
     */
    public function addModule(\AppBundle\Entity\Modules $module)
    {
        $module->setProducts($this);
        $this->module[] = $module;

    }

    //...

}

Entity Modules.php

<?php
namespace AppBundle\Entity;

use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

/**
 * Modules
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="AppBundle\Entity\ModulesRepository")
 */
class Modules
{
    //...

    /**
     * @ORM\ManyToOne(targetEntity="Products", inversedBy="module")
     * @ORM\JoinColumn(name="product_id", referencedColumnName="id")
     */
    protected $products;


    /**
     * Constructor
     */
    public function __construct() {
        $this->products = new ArrayCollection();
    }

    /**
     * Set products
     *
     * @param \AppBundle\Entity\Products $products
     * @return Modules
     */
    public function setProducts(\AppBundle\Entity\Products $products = null)
    {
        $this->products = $products;

        return $this;
    }

    /**
     * Get products
     *
     * @return \AppBundle\Entity\Products 
     */
    public function getProducts()
    {
        return $this->products;
    }

    //...
}

Entity admin.yml

services:

    sonata.admin.product.modules:
        class: AppBundle\Admin\ModulesAdmin
        tags:
            - {name: sonata.admin, manager_type: orm, label: Products}
        arguments:
            - ~
            - AppBundle\Entity\Modules
            - 'SonataAdminBundle:CRUD'
        calls:
            - [ setTranslationDomain, [ProductsAdmin]]
            - [ setLabelTranslatorStrategy, ["@sonata.admin.label.strategy.underscore"]]

Entity ProductsAdmin.php

<?php

namespace AppBundle\Admin;

class ProductsAdmin extends Admin {

    public $supportsPreviewMode = true;
    protected $formOptions = array(
        'cascade_validation' => true        
    );

    //...

    protected function configureFormFields(FormMapper $formMapper) {

        $formMapper
                ->tab('General')
                ->end()  
                ->tab('Modules')        
                    ->add('module', 'sonata_type_collection', array(
                        'type_options' => array(
                            'delete' => true
                        )
                            ), array(
                        'edit' => 'inline',
                        'inline' => 'table',
                        'sortable' => 'position',
                        'admin_code' => 'sonata.admin.product.modules'
                    ))       
                ->end()   
        ;
    }

    public function prePersist($products) {
        $this->preUpdate($products);
    }

    public function preUpdate($products) {

        $products->setModule($products->getModule());
    }

    //...

}

Entity ModulesAdmin.php

<?php

namespace AppBundle\Admin;

class ModulesAdmin extends Admin {

    public $supportsPreviewMode = true;
    protected $formOptions = array(
        'cascade_validation' => true
    );
    protected $baseRouteName = 'admin_app_product_modules';
    protected $baseRoutePattern = 'app/product-modules';

    //...

}

I would like to know how to indicate the tab where the embedded form, there is a validation error in their fields is.


回答1:


This has probably already been fixed but I fixed it this way:

In my Admin Class I added:

protected $formOptions = array(
    'cascade_validation' => true        
);

Also in my sonata_type_collection entries I added:

'cascade_validation' => true

This causes the element on the form to add either the class 'has-error' in case of non-embedded forms, or 'error' in case of embedded sonata_type_collection inline forms, when there was a validation error.

In order to highlight the correct tab I had to use jQuery. By default the tab buttons themselves always contain the following:

<i class="fa fa-exclamation-circle has-errors hide"></i>

So it was easy enough to target this with a little bit of code and remove that 'hide' class.

// Highlight tabs if there is a validation error on an element in them
$('.tab-pane').each( function( index, element ) {
    var btn = $('a[href^="#'+$(this).attr('id')+'"]');
    var jumpToTab = false;
    $(this).find('td, div').each(function(i, e) {
        if ($(this).hasClass('error') || $(this).hasClass('has-error')) {
            if (jumpToTab == false) {
                btn.tab('show');
                jumpToTab = true;
            }
            btn.find('i').removeClass('hide');
            btn.addClass('error');
        }
    });
});

I added an 'error' class to the btn because I wanted to change the link colour as well, but that's it. Submitting the form with errors now highlights all tabs that have elements in them that have errored.



来源:https://stackoverflow.com/questions/35925712/sonataadminbundle-embebed-form-validation-error

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!