Sonata Admin-bundle:从ajax请求中提交值

时间:2014-02-19 11:33:00

标签: javascript jquery ajax symfony sonata-admin

与此问题完全相同的问题:

Dropdown Ajax onchange SonataAdminBundle Symfony2 Issue

当我选择“值1”下拉列表时,表单会向我的curstom CRUD控制器发送一个ajax请求,该控制器返回附加第二个下拉列表的值(“id de l'element”)。

enter image description here

事实上,一切正常,但是当我想提交所有表单来创建我的新对象时,奏鸣曲会抛出一个错误,而我之前选择的所有值都已消失。

enter image description here

在挖掘生成的html代码后,我确认我的ajax请求正确填充了用于显示下拉列表的第二个选择(“id de l'element”)。

但奏鸣曲似乎没有得到正确的值。

任何想法?

已编辑:

我做了一个小技巧,但它非常随意。

我在formMapper中填充了可能的选项,其中包含一个2000索引的数组(用简单的循环制作)

因为我只需要整数键,所以它可以工作,但它不是通用的,并且dom需要花费大量时间才能在我的选择中生成2000个选项。

我无法想象奏鸣曲开发者没有使用ajax请求使其捆绑可用.....

我的实体

  namespace myapp\AppBundle\Entity;

  use Doctrine\ORM\Mapping as ORM;

/**
 * statistics
 *
 * @ORM\Table()
 * @ORM\Entity
 */
  class Statistics
  {
/**
 * @var integer
 *
 * @ORM\Column(name="id", type="integer")
 * @ORM\Id
 * @ORM\GeneratedValue(strategy="AUTO")
 */
private $id;

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 */
private $name;

/**
 * @var string
 *
 * @ORM\Column(name="firstValue", type="string", length=255)
 */
private $firstValue;

/**
 * @var string
 *
 * @ORM\Column(name="filter1", type="string")
 */
private $filter1;

/**
 * @var string
 *
 * @ORM\Column(name="secondValue", type="string", length=255)
 */
private $secondValue;

/**
 * @var string
 *
 * @ORM\Column(name="filter2", type="string", length=255)
 */
private $filter2;


/**
 * @var string
 *
 * @ORM\Column(name="periodicity", type="string", length=255)
 */
private $periodicity;

这是我的统计管理类:

class statisticsAdmin extends Admin
 {
protected $baseRouteName                = 'stats';
protected $baseRoutePattern             = 'stats';

private $em;
private $bundles;
private $entities;
private $app;

public $filter1Values;
public $filter2Values;


public function getTemplate($name)
{
    if ( $name == "edit" )
        return 'bonkAppBundle:Admin:base_edit.html.twig' ;
    return parent::getTemplate($name);
}

/**
 * Récupères l'ensemble des entités disponible pour le projet
 * en cours.
 *
 * On fait établit un filtre pour éviter que le bundle FOSUser
 * soit pris en compte (il est inclus depuis l'entiti User
 *
 * les données collectés sont enregistrés dans une variable de class
 * $this->bundles
 * @return null
 */
public function getAllEntities()
{
    $this->em                       = $this->modelManager->getEntityManager('bonk\AppBundle\Entity\Statistics');
    $this->bundles                  = $this->em->getConfiguration()->getMetadataDriverImpl()->getAllClassNames();
    $this->app                      = 'bonk';

    foreach ( $this->bundles as $bundle )
    {
        $temp                       = explode ( '\\', $bundle );

        if ( $temp[0] == 'bonk' ){
            $class                  = $this->em->getClassMetadata( $temp[0].$temp[1].":".$temp[3] );
            $associations           = $class->getAssociationNames();

            //foreach ( $class->fieldMappings as $field )
            //    $this->entities[$temp[0].$temp[1].":".$temp[3]][$temp[0].$temp[1].":".$temp[3].":".$field['fieldName']] = $field['fieldName'] ;

            // on ajoute les relations de l'entite . We also add associations for the given entity class
            foreach ( $associations as $association ){
                $AssociatedEntity   = explode ( "\\", $class->getAssociationTargetClass( $association ) );
                $this->entities[$temp[0].$temp[1].":".$temp[3]][$AssociatedEntity[0].$AssociatedEntity[1].":".$AssociatedEntity[3]] = $association ;
            }
        }
    }
}


protected function configureFormFields(FormMapper $formMapper)
{
    $this->getAllEntities();

    $temp = array();
    //for ( $a = 1; $a < 2000 ; $a++ )
    //    $temp[$a] = "a";

    $formMapper
        ->with('General')
            ->add('name', null, array ( 'label' => 'Titre') )
            ->add('firstValue', 'choice', array ( 'label' => 'Valeur 1', 'choices' => $this->entities ) )
            ->add('filter1' , 'choice' , array ( 'choices' => array('all' => 'Tout') ) )
            ->add('secondValue','choice', array ( 'label' => 'Valeur 2', 'choices' => $this->entities ) )
            ->add('filter2' , 'choice' , array ( 'choices' => array('all' => 'Tout') ) )
            ->add('periodicity','choice', array ( 'label' => 'Durée'   , 'choices' => array( 
                                                    '1 hour'    => '1 Heure',
                                                    '1 day'     => '1 Jour',
                                                    '1 week'    => '1 Semaine', 
                                                    '1 month'   => '1 Mois',
                                                    '3 months'  => '1 Trimestre',
                                                    '6 months'  => '1 Semestre',
                                                    '1 year'    => '1 Annee',
                                                    '2 year'    => '2 Annees' ) ) )
        ->end()
    ;
}

protected function configureListFields(ListMapper $listMapper)
{
    $listMapper
            ->addIdentifier('name', null, array ( 'label' => 'Titre') )
            ->add('firstValue', null, array ( 'label' => 'Valeur 1') )
            ->add('filter1', null, array ( 'label' => 'filtre 1') )
            ->add('secondValue', null, array ( 'label' => 'Valeur 2') )
            ->add('filter2', null, array ( 'label' => 'filtre 2') )
            ->add('periodicity', null, array ( 'label' => 'Durée') )
            ->add('_action', 'actions', array(
            'actions' => array(
                'Clone' => array('template' => 'bonkAppBundle:CRUD:stat.html.twig'),
                'edit' => array(),
                'delete' => array(),
            )
        ))
    ;
}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'error_mapping' => array(
            'test' => 'filter1Ajax',
        ),
    ));
}


/**
 * Ajoute une route pour l'admin
 *
 * La nouvelle vue sera disponible par la route spécifiée dans
 * $collection par la méthode "add"
 */
protected function configureRoutes( RouteCollection $collection )
{
    $collection->add('stat', $this->getRouterIdParameter().'/stat');
}

然后我的javascript在我的自定义覆盖base_edit.html.twig:

{% block javascripts %}
{{ parent() }}
<script src="{{ asset('bundles/fosjsrouting/js/router.js') }}"></script>
<script src="{{ path('fos_js_routing_js', {"callback": "fos.Router.setData"}) }}"></script>
<script type="text/javascript" src="{{ asset( 'public/js/chosen.jquery.min.js' ) }}"></script>
<script type="text/javascript">

    $(document).ready(function(){
        var firstValue          = $("#{{ admin.uniqId }}_firstValue");
        firstValue.change(updateValues('firstValue'));

        var secondValue         = $("#{{ admin.uniqId }}_secondValue");
        secondValue.change(updateValues('secondValue', true ));

        function updateValues(value, secondValue = false){
            return function () {

                if ( secondValue == false ){
                    var tagId   = $("#{{ admin.uniqId }}_firstValue option:selected").val();
                    var filter1 = $("#{{ admin.uniqId }}_filter1");
                }else{
                    var tagId   = $("#{{ admin.uniqId }}_secondValue option:selected").val();
                    var filter1 = $("#{{ admin.uniqId }}_filter2");
                }

                filter1.empty();
                filter1.trigger("chosen:updated");

                var locale      = '{{ app.request.get('_locale') }}';
                var objectId    = '{{ admin.id(object) }}'

                $.ajax
                ({
                    type:   'POST',
                    url :   Routing.generate('myapp_admin_get_values_from_entities', { '_locale': locale, 'tagId': tagId, _sonata_admin: 'myapp.app.admin.stats', id: objectId }) ,
                    data:   tagId,
                    cache:  false,
                    error:function ( xhr, ajaxOptions, thrownError ) 
                    {
                        alert(xhr.status + " " + thrownError);
                    },
                    success:function( html )
                    {
                        filter1.empty();
                        filter1.append(html);
                        filter1.trigger("chosen:updated");
                        filter1.val('option:first').attr('selected', true );
                    }
                });
            };
        }
    });
</script>
{% endblock %}

0 个答案:

没有答案