Symfony中的多个地址的一种形式 - Twig

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Symfony中的多个地址的一种形式 - Twig相关的知识,希望对你有一定的参考价值。

首先,我想说清楚我没有使用Entities / Doctrine作为我的表单(甚至是)。我正在使用webservices来添加/编辑数据库的数据字段

我正在开展一个项目,我需要用多个地址编辑公司信息。第一个地址始终是物理地址,因此我在与公司数据相同的循环中获取它。

但是,第二个(以及第三个或第四个,如果存在的)地址放在单独的数据库条目中。我能够用一个表单编辑公司数据和公司地址(物理地址)(因为数据都在一个集合中)因此我只需要一个表单,而不必使用循环地址。


现在我要编辑第二个地址。我正在循环遍历树枝中的地址并打印出该公司的所有其他地址。我知道Symfony不允许同一个表单的多个实例,因为这会干扰ID等。

问题是我应该如何仅为特定地址呈现表单。我想通过点击一个按钮进行编辑(如果不编辑则使用bootstrap折叠来隐藏表单)

我的代码看起来像这样:

控制器:

public function editcompany(Request $request, $klantnr)
{

    [...]

    $result = [
        'gegevens' => [],
        'addresses' => [],
    ];

    foreach ($company as $row) {
        $dataFields = [
            [...] // The data fields of the company (including the physical address)
        ];
        foreach ($dataFields as $dataField) {
            if (empty($result['gegevens'][$dataField])) {
                $result['gegevens'][$dataField] = $row[$dataField];
            }
        }
        if($row['AdrGid'] != $result['gegevens']['AdrGid']) {
            $result['addresses'][$row['AdrGid']] = [
                [...] // The data fields for the other addresses 
            ];
        }
    }

    // The form creation of the company data form
    $form = $this->createForm(EditcompanyForm::class);

    // The form of the other addresses
    $form_adres = $this->createForm(EditcompanyAdresForm::class, array(
        [...]
    ));
    $form->handleRequest($request);
    $form_adres->handleRequest($request);


    if($form->isSubmitted() && $form->isValid()) {
        [...] // Handling the submitted data for the company data
    }

    // GEKOPPELDE ADRESSEN company
    if($form_adres->isSubmitted() && $form_adres->isValid()) {

        [...]

        $data = array(
            [...] // Setting the data for the other addresses
        );

        [...]

        // Passing the data and other options to the webservices
        $this->get('http')->companyRequest($data, $admincode, $service, $token);

        $request->getSession()
            ->getFlashBag()
            ->add('success', 'Linked address successfully edited');

        return $this->redirect($request->getUri());
    }

    return $this->render('pages/company/edit.html.twig', array(
        'client' => $result,
        'form_company' => $form->createView(),
        'form_company_adres' => $form_adres->createView()
    ));
 }

Formbuilder(AbstractType):

class EditcompanyAdresForm extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $factuuradres = $options['NawFactuurAdres'];
        $lands = $options['lands'];

        $data = array();
        $builder
            [...] // Add the necessary fields
    }
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            [...] // setting defaults here
        ));
    }
    /**
     * {@inheritdoc}
     */
    public function getBlockPrefix()
    {
        return 'appbundle_form_editcompanyadresform';
    }
}

树枝模板(显示地址:

{% for address in client.addresses %}
    <div class="right-cont-grey">
        [...] // showing addresses
    </div>
{% endfor %}

Twig模板(编辑表格):

{% for address in client.addresses %}
    {{ form_start(form_company_adres, {'  method': 'POST'}) }}
    {{ form_row(form_company_adres._token) }}
        <section class="collapse" id="adres_plus">
            <div id="adres" class="new-adres collapse right-cont-grey">
                <div class="col-sm-12">
                    [...] // Form_widgets with values from database
            </div>
        </section>
    {{ form_end(form_company_adres) }}
{% endfor %}

简而言之:

如何在没有干扰的情况下为每个地址使用地址表单?也许在循环内的twig文件中创建视图(渲染)?我的表单预先填充了数据库中的数据,以便我可以编辑它。

答案

关于我们在聊天中谈到的内容的修订答案:

正如我在评论中所写,我相信你只需要设置一个collection field。整个复杂性基本上消失了。

一个非常简单的例子是:

控制器:

public function editCompanyAction(Request $request)
{
    // get the data anyway you see fit and produce a model (this could also be a dedicated DTO)
    $company = $this->getInput();

    // create the form
    $form = $this
        ->createForm(CompanyWithAddressesType::class, $company)
        ->handleRequest($request)
    ;

    // handle submission
    if ($form->isSubmitted() && $form->isValid()) {
        dump($form->getData()); // === $company
    }

    return $this->render('default/index.html.twig', [
        'form' => $form->createView(),
    ]);
}

形式

这里重要的部分是你添加的字段的名称与数组中作为数据提供的键匹配!

class CompanyWithAddressesType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // combine the company with a collection of addresses:
        $builder
            ->add('gegevens', CompanyType::class)
            ->add('addresses', CollectionType::class, [
                'entry_type' => AddressType::class,
            ])
        ;
    }
}

class CompanyType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // all the fields that are *extra* for companies, address fields are inherited
        // because this type extends the address type (see below getParent)
        $builder
            ->add('NawWebsite', TextType::class)
            ->add('email1', TextType::class)
            ->add('AdrNaam1', TextType::class)
        ;
    }

    /**
     * @return @inheritdoc
     */
    public function getParent()
    {
        return AddressType::class;
    }
}

class AddressType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        // all the fields that define an address
        $builder
            ->add('AdrStraat', TextType::class)
            ->add('AdrHuisnummer', TextType::class)
            ->add('AdrPostcode', TextType::class)
            ->add('NawFactuurAdres', CheckboxType::class)
        ;
    }
}

枝条:

只需输出表格即可。任何form customization都适用

{{ form_start(form) }}
    <div>
        <h4>Company</h4>
        {{ form_row(form.gegevens.NawWebsite) }}
        {{ form_row(form.gegevens.email1) }}
        {{ form_row(form.gegevens.AdrNaam1) }}
    </div>

    <div>
        <h4>Main address</h4>
        {{ form_rest(form.gegevens) }}
    </div>

    <div>
        <h4>Extra addresses</h4>
        {% for address in form.addresses %}
            {{ form_errors(address) }}
            {{ form_widget(address) }}
        {% endfor %}
    </div>

    <button>Submit</button>
{{ form_end(form) }}
另一答案

我认为你需要将表单放在循环之外,然后有一个隐藏的输入字段,用于标识需要在提交时保存的地址。因此,当未显示其他字段时,不会提交它们。这意味着您需要一些javascript逻辑来显示和隐藏地址。

Twig模板(编辑表格):

{{ form_start(form_company_adres, {'  method': 'POST'}) }}
{% for address in client.addresses %}
    <div id="address-{{ loop.index }}" class="address">
        <input type="hidden" name="address-number" value="{{ loop.index }}"/>
        {{ form_row(form_company_adres._token) }}
            <section class="collapse" id="adres_plus">
                <div id="adres" class="new-adres collapse right-cont-grey">
                    <div class="col-sm-12">
                        [...] // Form_widgets with values from database
                </div>
            </section>
    </div>
{% endfor %}
{{ form_end(form_company_adres) }}

以上是关于Symfony中的多个地址的一种形式 - Twig的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 中的 Twig CamelCase 过滤器

Symfony2 twig 移动模板后备

使用 Assetic / Twig / Symfony2,我可以定义前端库吗?

从 Symfony2/Twig 中的 2 位国家代码获取翻译的国家名称?

Symfony2 和 Twig 在 vagrant box 中的表现

Symfony/Twig 在 if 条件下设置变量