【问题标题】:Symfony JavaScript dropdown working correctly in one location, but not in anotherSymfony JavaScript 下拉菜单在一个位置正常工作,但在另一个位置不能正常工作
【发布时间】:2017-12-19 15:04:58
【问题描述】:

我正在为级联多选下拉菜单使用可重用的 JavaScript 代码。对于其中一种用法,它运行良好,但在我使用完全相同代码的另一个位置,它不是。

发生的情况是,我创建了分配给根据产品、渠道和市场选择的代理机构 (IATA) 的文档(非工作点)和 UploadProfiles(工作点)。

为什么它不起作用:

  1. 当我将渠道和产品作为数组集合添加到我的文档实体构造函数时,我的文档在提交后根本没有分配给任何渠道或产品。
  2. 当我从构造函数中删除它们并提交表单时,我收到以下错误消息

调用数组上的成员函数 removeElement()

我将复制我的实体和 JavaScript 代码。

文档实体

  <?php

namespace DocumentBundle\Entity;

use AppBundle\Entity\FileAwareEntity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Bundle\DoctrineBundle\Registry;
use Doctrine\Common\Collections\ArrayCollection;
use FS\SolrBundle\Doctrine\Annotation as Solr;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\ExecutionContextInterface;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\Security\Core\Security;
use UserBundle\Entity\User as User;


/**
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Table(name="document_document", options={"engine"="InnoDB"})
 * @ORM\Entity(repositoryClass="DocumentBundle\Entity\DocumentRepository")
 */
class Document extends FileAwareEntity {
    /**
     * @ORM\Column(type="integer")
     * @Solr\Id
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

     /**
     * @Solr\Field(type="string")
     * @Assert\NotBlank()
     * @var string
     * @ORM\Column(type="string")
     */
    private $name;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Agency", inversedBy="documentagencies", cascade={"persist"})
     * @ORM\JoinTable(name="document_document_agencies",
     *   joinColumns={@ORM\JoinColumn(name="document_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="iata8", referencedColumnName="iata8")})
     * @var \AppBundle\Entity\Agency
     **/
    private $agencies;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Market", inversedBy="documents", cascade={"persist"})
     * @ORM\JoinTable(name="document_document_markets",
     *   joinColumns={@ORM\JoinColumn(name="document_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="market_id", referencedColumnName="id")})
     * @Assert\Count(
     *      min = "0"
     * )
     **/
    private $markets;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Airline", inversedBy="documents", cascade={"persist"})
     * @ORM\JoinTable(name="document_document_airlines",
     *   joinColumns={@ORM\JoinColumn(name="document_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="airline_id", referencedColumnName="id")})
     * @Assert\Count(
     *      min = "0"
     * )
     * @var \AppBundle\Entity\Airline
     **/
    private $airlines;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Product", inversedBy="documents", cascade={"persist"})
     * @ORM\JoinTable(name="document_document_products",
     *   joinColumns={@ORM\JoinColumn(name="document_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")})
     * @Assert\Count(
     *      min = "0"
     * )
     * @var \AppBundle\Entity\Product
     **/
    private $products;

    /**
     * @ORM\ManyToMany(targetEntity="ReferentialBundle\Entity\Channel1", inversedBy="documents", cascade={"persist"})
     * @ORM\JoinTable(name="document_document_channel1",
     *   joinColumns={@ORM\JoinColumn(name="document_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="channel1_id", referencedColumnName="id")})
     * @Assert\Count(
     *      min = "0"
     * )
     * @var \ReferentialBundle\Entity\Channel1
     **/

    private $channel1;

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->locked = false;
        $this->signed = false;
        $this->markets = new \Doctrine\Common\Collections\ArrayCollection();
        $this->agencies = new \Doctrine\Common\Collections\ArrayCollection();
        // $this->channel1 = new \Doctrine\Common\Collections\ArrayCollection();
        // $this->products = new \Doctrine\Common\Collections\ArrayCollection();
        // $this->airlines = new \Doctrine\Common\Collections\ArrayCollection();
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    function setId($id) {
        $this->id = $id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return Document
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    /**
     * Add agency
     *
     * @param \AppBundle\Entity\Agency $agency
     *
     * @return Document
     */
    public function addAgency(\AppBundle\Entity\Agency $agency)
    {
        $this->agencies[] = $agency;

        return $this;
    }

    /**
     * Remove agency
     *
     * @param \AppBundle\Entity\Agency $agency
     */
    public function removeAgency(\AppBundle\Entity\Agency $agency)
    {
        $this->agencies->removeElement($agency);
    }

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

    /**
     * Add market
     *
     * @param \AppBundle\Entity\Market $market
     *
     * @return Document
     */
    public function addMarket(\AppBundle\Entity\Market $market)
    {
        $this->markets[] = $market;

        return $this;
    }

    /**
     * Remove market
     *
     * @param \AppBundle\Entity\Market $market
     */
    public function removeMarket(\AppBundle\Entity\Market $market)
    {
        $this->markets->removeElement($market);
    }

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

    /**
     * Add airline
     *
     * @param \AppBundle\Entity\Airline $airline
     *
     * @return Document
     */
    public function addAirline(\AppBundle\Entity\Airline $airline)
    {
        $this->airlines[] = $airline;

        return $this;
    }

    /**
     * Remove airline
     *
     * @param \AppBundle\Entity\Airline $airline
     */
    public function removeAirline(\AppBundle\Entity\Airline $airline)
    {
        $this->airlines->removeElement($airline);
    }

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

    /**
     * Add product
     *
     * @param \AppBundle\Entity\Product $product
     *
     * @return Document
     */
    public function addProduct(\AppBundle\Entity\Product $product)
    {
        $this->products[] = $product;

        return $this;
    }

    /**
     * Remove product
     *
     * @param \AppBundle\Entity\Product $product
     */
    public function removeProduct(\AppBundle\Entity\Product $product)
    {
        $this->products->removeElement($product);
    }

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

    /**
     * Add channel1
     *
     * @param \ReferentialBundle\Entity\Channel1 $channel1
     *
     * @return Document
     */
    public function addChannel1(\ReferentialBundle\Entity\Channel1 $channel1)
    {
        $this->channel1[] = $channel1;

        return $this;
    }

    /**
     * Remove channel1
     *
     * @param \ReferentialBundle\Entity\Channel1 $channel1
     */
    public function removeChannel1(\ReferentialBundle\Entity\Channel1 $channel1)
    {
        $this->channel1->removeElement($channel1);
    }

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

上传个人资料实体

   <?php

namespace DocumentBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\Airline;
use Doctrine\ORM\Event\PreFlushEventArgs;
use Doctrine\ORM\Event\LifeCycleEventArgs;

/**
 * @ORM\Entity
 * @ORM\HasLifecycleCallbacks()
 * @ORM\Entity(repositoryClass="DocumentBundle\Entity\UploadProfileRepository")
 * @ORM\Table(name="document_uploadprofile", options={"engine"="InnoDB"})
 */
class UploadProfile{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(type="string", length=100)
     */
    private $name;
  /**
    * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Market", inversedBy="uploadProfiles", cascade={"persist"})
    * @ORM\JoinTable(name="document_uploadprofile_markets",
    *   joinColumns={@ORM\JoinColumn(name="uploadprofile_id", referencedColumnName="id")},
    *   inverseJoinColumns={@ORM\JoinColumn(name="market_id", referencedColumnName="id")})
    **/
    private $markets;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Agency", inversedBy="uploadProfiles", cascade={"persist"})
     * @ORM\JoinTable(name="document_uploadprofile_agencies",
     *   joinColumns={@ORM\JoinColumn(name="uploadprofile_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="iata8", referencedColumnName="iata8")})
     **/
    private $agencies;

    /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Airline", inversedBy="uploadProfiles", cascade={"persist"})
     * @ORM\JoinTable(name="document_uploadprofile_airlines",
     *   joinColumns={@ORM\JoinColumn(name="uploadprofile_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="airline_id", referencedColumnName="id")})
     * @var \AppBundle\Entity\Airline
     **/

    private $airlines;


    /**
     * @ORM\ManyToMany(targetEntity="ReferentialBundle\Entity\Channel1", inversedBy="uploadProfiles", cascade={"persist"})
     * @ORM\JoinTable(name="document_uploadprofile_channel1",
     *   joinColumns={@ORM\JoinColumn(name="uploadprofile_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="channel1_id", referencedColumnName="id")})
     * @var \ReferentialBundle\Entity\Channel1
     **/
    private $channel1;
  /**
     * @ORM\ManyToMany(targetEntity="AppBundle\Entity\Product", inversedBy="uploadProfiles", cascade={"persist"})
     * @ORM\JoinTable(name="document_uploadprofile_products",
     *   joinColumns={@ORM\JoinColumn(name="uploadprofile_id", referencedColumnName="id")},
     *   inverseJoinColumns={@ORM\JoinColumn(name="product_id", referencedColumnName="id")})
     * @Assert\Count(
     *      min = "1"
     * )
     * @var \AppBundle\Entity\Product
     **/
    private $products;

  /**
     * Constructor
     */
    public function __construct()
    {
        $this->agencies = new \Doctrine\Common\Collections\ArrayCollection();
        $this->markets = new \Doctrine\Common\Collections\ArrayCollection();
          // $this->channel1s = new \Doctrine\Common\Collections\ArrayCollection();
          // $this->channel3s = new \Doctrine\Common\Collections\ArrayCollection();
        $this->locked = false;
        $this->archived = false;
    }

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    function setId($id) {
        $this->id = $id;
    }

  /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }
    /**
     * Set name
     *
     * @param string $name
     * @return UploadProfile
     */
    public function setName($name)
    {
        $this->name = $name;

        return $this;
    }


    /**
     * Add market
     *
     * @param \AppBundle\Entity\Market $market
     *
     * @return UploadProfile
     */
    public function addMarket(\AppBundle\Entity\Market $market)
    {
        $this->markets[] = $market;

        return $this;
    }

    /**
     * Remove market
     *
     * @param \AppBundle\Entity\Market $market
     */
    public function removeMarket(\AppBundle\Entity\Market $market)
    {
        $this->markets->removeElement($market);
    }

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

    /**
     * Add agency
     *
     * @param \AppBundle\Entity\Agency $agency
     *
     * @return UploadProfile
     */
    public function addAgency(\AppBundle\Entity\Agency $agency)
    {
        $this->agencies[] = $agency;

        return $this;
    }

    /**
     * Remove agency
     *
     * @param \AppBundle\Entity\Agency $agency
     */
    public function removeAgency(\AppBundle\Entity\Agency $agency)
    {
        $this->agencies->removeElement($agency);
    }

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

    /**
     * Add airline
     *
     * @param \AppBundle\Entity\Airline $airline
     *
     * @return UploadProfile
     */
    public function addAirline(\AppBundle\Entity\Airline $airline)
    {
        $this->airlines[] = $airline;

        return $this;
    }

    /**
     * Remove airline
     *
     * @param \AppBundle\Entity\Airline $airline
     */
    public function removeAirline(\AppBundle\Entity\Airline $airline)
    {
        $this->airlines->removeElement($airline);
    }

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

    /**
     * Add channel1
     *
     * @param \ReferentialBundle\Entity\Channel1 $channel1
     *
     * @return UploadProfile
     */
    public function addChannel1(\ReferentialBundle\Entity\Channel1 $channel1)
    {
        $this->channel1[] = $channel1;

        return $this;
    }

    /**
     * Remove channel1
     *
     * @param \ReferentialBundle\Entity\Channel1 $channel1
     */
    public function removeChannel1(\ReferentialBundle\Entity\Channel1 $channel1)
    {
        $this->channel1->removeElement($channel1);
    }

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

    /**
     * Add product
     *
     * @param \AppBundle\Entity\Product $product
     *
     * @return UploadProfile
     */
    public function addProduct(\AppBundle\Entity\Product $product)
    {
        $this->products[] = $product;

        return $this;
    }

    /**
     * Remove product
     *
     * @param \AppBundle\Entity\Product $product
     */
    public function removeProduct(\AppBundle\Entity\Product $product)
    {
        $this->products->removeElement($product);
    }

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

我的 JavaScript 函数(尽管我不敢相信错误就在那里,因为两者的代码是 1:1 相同的):

    <script type="text/javascript">

var message = false;

// Form dropdown disabling
$(document).ready(function(){

  // disable channel, product, agency
  init_MCPA_DDs();
  document.getElementById("___before-submit___").disabled = true;

});

$('#helpModal').on('show.bs.modal', function (event) {
  var button = $(event.relatedTarget) // Button that triggered the modal
  header = button.data('header') // Extract info from data-* attributes
  text = button.data('text')
  var modal = $(this)
  modal.find('.modal-title').text(header)
  modal.find('.modal-body').text(text)
});

// Market->Channel1->Product->Agency Selection

function init_MCPA_DDs()
{
  $('#{{ form.vars.name }}_channel1').multiselect('disable');
  $('#{{ form.vars.name }}_products').multiselect('disable');
  $('#{{ form.vars.name }}_agencies').multiselect('disable');
  //
  $('#{{ form.vars.name }}_markets').on("change",function() {
    if($(this).val() != null) {
      $('#{{ form.vars.name }}_channel1').multiselect('enable');
    }
  });
}

function refresh_all_ms()
{
  // BS MS SA Fix
  $('#{{ form.vars.name }}_markets').multiselect('refresh');
  $('#{{ form.vars.name }}_channel1').multiselect('refresh');
  $('#{{ form.vars.name }}_products').multiselect('refresh');
  $('#{{ form.vars.name }}_agencies').multiselect('refresh');
}

function reset_P()
{
  $('#{{ form.vars.name }}_products').empty();
  $('#{{ form.vars.name }}_products').multiselect('rebuild');
  $('#{{ form.vars.name }}_products').multiselect('disable');
}

function reset_A()
{
  $('#{{ form.vars.name }}_agencies').empty();
  $('#{{ form.vars.name }}_agencies').multiselect('rebuild');
  $('#{{ form.vars.name }}_agencies').multiselect('disable');
  document.getElementById("___before-submit___").disabled = true;
}

function reset_PA()
{
  reset_P();
  reset_A();
}

var market_data = new String('___');
var channel1_data = new String('____');
var product_data = new String('____');
makeMultiselectDropdown('#{{ form.vars.name }}_airlines', 'Select Airlines' );

makeMultiselectDropdown('#{{ form.vars.name }}_markets', 'Select Markets', {
  onDropdownShown: function(event) {
    market_data = $('#{{ form.vars.name }}_markets').val();
    if (market_data == null) { market_data = '___'; }
  },
  onDropdownHide: function(event) {
    var md = $('#{{ form.vars.name }}_markets').val();
    if (md == null) {
      md = '____';
      reset_PA();
    }
    if (market_data.toString().localeCompare(md)) {
      reset_PA();
      handleMarketChannelChoice(true);
    }
    refresh_all_ms();
  }
});

makeMultiselectDropdown('#{{ form.vars.name }}_channel1', 'Select Channel', {
  onDropdownShown: function(event) {
    channel1_data = $('#{{ form.vars.name }}_channel1').val();
    if (channel1_data == null) { channel1_data = '____'; }
  },
  onDropdownHide: function(event) {
    var cd = $('#{{ form.vars.name }}_channel1').val();
    if (cd == null) {
      cd = '____';
      reset_PA();
    }
    if (channel1_data.toString().localeCompare(cd)) {
      reset_PA();
      handleMarketChannelChoice(true);
    }
    refresh_all_ms();
  }
});

makeMultiselectDropdown('#{{ form.vars.name }}_products', 'Select Products', {
  onDropdownShown: function(event) {
      product_data = $('#{{ form.vars.name }}_products').val();
      if (product_data == null) { product_data = '___'; }
    },
  onDropdownHide: function(event) {
    var pd = $('#{{ form.vars.name }}_products').val();
    if (pd == null) {
      pd = '____';
      reset_A();
    }
    if (product_data.toString().localeCompare(pd)) {
      reset_A();
      handleProductChoice(true);
    }
    refresh_all_ms();
  }
});

makeMultiselectDropdown('#{{ form.vars.name }}_agencies', 'Select Agencies', {
  onDropdownHide: function(event) {
    refresh_all_ms();
  },
  onDropdownHide: function(event) {
    var ad = $('#{{ form.vars.name }}_agencies').val();
    if (ad !== null && ad !=='text') {
        document.getElementById("___before-submit___").disabled = false;
    }

  }
});

//Populate Product dropdown
function handleMarketChannelChoice() {

    var channel1 = $('#{{ form.vars.name }}_channel1').val();
    var market = $('#{{ form.vars.name }}_markets').val();

    if (market === null || channel1 === null) return false;

    path = "{{ path('documentBundle_marketChannelData') }}";

    $.get(path,
        {market: market, channel1: channel1},
        function(response) {
            response = JSON.parse(response);
            if(response.code == '100' && response.success) {
                $('#{{ form.vars.name }}_products').empty();
                for (var i=0; i<response.productName.length; i++) {
                    $('#{{ form.vars.name }}_products').append($('<option>', {
                                            value: response.productId[i],
                                                text: response.productName[i]
                                            }));
                }
                $('#{{ form.vars.name }}_products').multiselect('rebuild');
                $('#{{ form.vars.name }}_products').multiselect('enable');

            } else {
                alert('No Products found for selected Market, Channel');
            }
        }
    );
}

//Populate Agency Dropdown
function handleProductChoice() {

    var product = $('#{{ form.vars.name }}_products').val();
    if (product === null) return false;
    path = "{{ path('documentBundle_productData') }}";

    $.get(path,
        {product: product,},
        function(response) {
            response = JSON.parse(response);
            if(response.code == '100' && response.success) {
                $('#{{ form.vars.name }}_agencies').empty();
                for (var i=0; i<response.agencyId.length; i++){
                    $('#{{ form.vars.name }}_agencies').append($('<option>', {
                                        value: response.agencyId[i],
                                            text: response.agencyName[i]
                                        }));
                }

                $('#{{ form.vars.name }}_agencies').multiselect('rebuild');
                $('#{{ form.vars.name }}_agencies').multiselect('enable');
            } else {
                alert('No Agencies found for selected Market, Channel, Product');
            }
        }
    );
}

</script>

对于上传配置文件,JavaScript 和表单类型包含在同一个 Twig 模板中,而不是访问其他 JavaScript。

对于文档,它有点复杂:有一个 create-twig-template,包括用于创建文档的表单类型,位于另一个 twig 模板中。 create-twig-template 和 form-twig-template 都包含 JavaScript 文件和另外两个 JavaScript 文件。

【问题讨论】:

  • 它包含我发帖时没有想到的敏感数据..

标签: javascript forms symfony


【解决方案1】:

如果这不是 SPA,那么这意味着您的 ID 相同(复制粘贴的味道)。只要确保它与 ID 不是 1:1 匹配即可。

     onDropdownHide: function(event) {
        var ad = $('#{{ form.vars.name }}_agencies').val();
        if (ad !== null && ad !=='text') {
/// make sure you the id doesn't already exist on the html page. ___before-submit___
            document.getElementById("___before-submit___").disabled = false;
        }

      }

还要验证 jQuery 是否确实绑定到元素并触发函数。

【讨论】:

  • 什么是 SPA,您指的是哪些 ID?这些函数都被触发了,因为它是不同的表单类型,所以它们是独一无二的
  • id 全局属性定义了一个唯一标识符(ID),它在整个文档中必须是唯一的。它的目的是在链接(使用片段标识符)、脚本或样式(使用 CSS)时识别元素。 link
  • 我知道 ID 是什么,我的 ID 都是唯一的。我只是不明白您的回答应该如何帮助我解决我的问题,我的功能都被正确触发。下拉菜单本身正在按照我希望它们使用正确数据的方式工作..
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-10-27
相关资源
最近更新 更多