2016-03-10 2 views
0

У меня есть класс администратора, в который входит другой класс администратора.SonataAdminBundle embebed form validation error

  • Symfony 2.7.9
  • Sonata Админ Bundle 2.3.7

Я его структурирована в виде вкладок, и проблема заключается в том, что при возникновении ошибки проверки в любом из полей встроенная форма никоим образом не помечена вкладкой, на которой она расположена.

Это мой пример кода: 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'; 

    //... 

} 

Я хотел бы знать, как указать на вкладку, где внедренная форма, есть ошибка проверки в их поля.

ответ

2

Это, вероятно, уже было исправлено, но я исправил это так:

В моем администраторе класса я добавил:

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

Также в моих записях sonata_type_collection я добавил:

'cascade_validation' => true 

Это приводит к тому, что элемент в форме добавляет либо «has-error» класса в случае незакрепленных форм, либо «ошибка» в случае встроенных встроенных форм sonata_type_collection, когда была ошибкой проверки.

Чтобы выделить правильную вкладку, мне пришлось использовать jQuery. По умолчанию кнопка вкладки сама всегда содержит следующее:

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

Так это было достаточно легко предназначаться это с небольшим количеством коды и удалить этот класс «скрыть».

// 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'); 
     } 
    }); 
}); 

Я добавил класс «ошибки» в баттона, потому что я хотел, чтобы изменить цвет ссылки, а также, но это так. При отправке формы с ошибками теперь выделяются все вкладки, в которых есть элементы в них с ошибкой.

+0

спасибо, я попробую;) –