2013-08-16 31 views
16

Tôi đã tạo một biểu mẫu với Symfony2 FormBuilder và tôi muốn vô hiệu hóa một trong các trường trong chế độ xem chỉnh sửa. Tôi thực sự giấu nó với một wrapper (display:none) nhưng tôi đã tự hỏi nếu có một cách tốt hơn để làm điều này. Mã của tôi trông giống như sau:Làm thế nào để vô hiệu hóa một trường trong chế độ xem chỉnh sửa bằng Symfony 2 FormBuilder

EntityType

public function buildForm(FormBuilderInterface $builder, array $options) { 
    $builder->add('fieldToDisabledInEditView'); 
    // ... 

EntityController

public function newAction() { 
    $entity = new Entity; 
    $form = $this->createForm(new EntityType, $entity); 
    // ... 
} 
public function editAction() { 
    $entity = new Entity; 
    $form = $this->createForm(new EntityType, $entity); 
    // ... 
} 

(cành lá) Mẫu mới

<form> 
    {{ form_row(form.fieldToDisabledInEditView) }} 
    {# ... #} 

Chỉnh sửa (cành lá) Template

<form> 
    <span class="theValueOfTheHiddenField">{{ entity.fieldToDisabledInEditView }}</span> 
    <div style="display:none"> 
     {{ form_row(form.fieldToDisabledInEditView) }} 
    </div> 
    {# ... #} 
+0

Tôi biết đây là một câu hỏi cũ nhưng nhận ra rằng màn hình hiển thị: none sẽ vẫn gửi giá trị ở dạng bị vô hiệu hóa sẽ không hiển thị. Vì vậy, bạn có thể xóa một số nội dung bạn không muốn. – shokora

Trả lời

24

Tôi nghĩ rằng bạn sẽ thấy rằng bạn sẽ có khác biệt khác giữa tạo và chỉnh sửa, đặc biệt là các nhóm xác nhận. Vì trình điều khiển của bạn biết thao tác nào đang được thực hiện thì hãy xem xét tạo hai loại biểu mẫu EditEntity và CreateEntity và sau đó sử dụng một cơ sở chung để giảm thiểu mã trùng lặp. @cheesemackfly cho biết cách thêm thuộc tính bị vô hiệu vào một phần tử.

Nhưng tất nhiên bạn có thể cảm thấy rằng có hai hình thức là một sự lãng phí cho sự khác biệt đơn giản như vậy. Trong trường hợp đó, thêm cờ ý định vào lớp học của bạn và đặt cờ đó vào bộ điều khiển

class EntityType 
{ 
    public function __construct($intention) 
    { 
     $this->intention = $intention; 

    ... 
    // Use $this->intention to tweak the form 

    } 
} 

// controller 
$form = $this->createForm(new EntityType('create'), $entity); 
OR 
$form = $this->createForm(new EntityType('edit'), $entity); 

Nếu bạn thực sự muốn tham gia vào đó thì hãy sử dụng di để bơm ý định.

// controller 
$formType = $this->get('entity.create.formtype'); 
OR 
$formType = $this->get('entity.edit.formtype'); 

Bằng việc sử dụng dịch vụ mà bạn có thể bắt đầu chỉ với một formtype và sau đó khi bạn kết thúc việc tách nó thành hai (mà bạn sẽ) điều khiển của bạn sẽ vẫn làm việc như trước đây.

Và một điều nữa, bạn thực sự có thể đặt thuộc tính bị vô hiệu hóa trực tiếp trong twig giả sử bạn đang sử dụng các mẫu khác nhau để chỉnh sửa/tạo. Vì vậy, không có thay đổi mã nào cả.

{{ form_row(form.yourField, { 'attr':{'disabled':'disabled'} }) }} 

======================= ============================= Cập nhật: 03 tháng 3 năm 2016

Chỉ trong trường hợp bất kỳ ai gặp vấn đề này, hãy lưu ý Symfony 3 không còn hỗ trợ có một lớp thực hiện nhiều loại biểu mẫu. Về cơ bản, bạn phải có các lớp loại biểu mẫu riêng lẻ ngay cả khi chúng gần như giống hệt nhau. Và không bao giờ thêm dữ liệu cá thể vào các loại biểu mẫu của bạn.

+0

Cảm ơn cả hai bạn (@cheesemacfly). Bây giờ tôi chỉ lấy phần '{{form_row (form.yourField, {'attr': {'disabled': 'disabled'}})}}', nhưng là một điều tốt để biết cách sửa đổi kiểu biểu mẫu mà không cần sao chép các biểu mẫu. Cảm ơn một lần nữa, nhiều đánh giá cao :) – viarnes

16

Đây là trường hợp điển hình mà bạn có thể sử dụng một thuê bao sự kiện vào một lớp học mẫu.
Trong trường hợp của bạn, nó phải là như:

// src/Acme/DemoBundle/Form/EventListener/AddfieldToDisabledInEditViewSubscriber.php 
namespace Acme\DemoBundle\Form\EventListener; 

use Symfony\Component\Form\FormEvent; 
use Symfony\Component\Form\FormEvents; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 

class AddfieldToDisabledInEditViewSubscriber implements EventSubscriberInterface 
{ 
    public static function getSubscribedEvents() 
    { 
     // Tells the dispatcher that you want to listen on the form.pre_set_data 
     // event and that the preSetData method should be called. 
     return array(FormEvents::PRE_SET_DATA => 'preSetData'); 
    } 

    public function preSetData(FormEvent $event) 
    { 
     $data = $event->getData(); 
     $form = $event->getForm(); 

     // check if the object is "new" 
     // If you didn't pass any data to the form, the data is "null". 
     // This should be considered a new object 
     if (!$data || !$data->getId()) { 
      $form->add('fieldToDisabledInEditView'); 
     } 
     else 
     { 
      $form->add('fieldToDisabledInEditView', null, array('disabled' => true)); 
      //If PHP >= 5.4 
      //$form->add('fieldToDisabledInEditView', null, ['disabled' => true]); 
     } 
    } 
} 

Và trong loại hình của bạn:

// src/Acme/DemoBundle/Form/Type/EntityType.php 
namespace Acme\DemoBundle\Form\Type; 

// ... 
use Acme\DemoBundle\Form\EventListener\AddfieldToDisabledInEditViewSubscriber; 

class EntityType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('your_field'); 
     //... 

     $builder->addEventSubscriber(new AddfieldToDisabledInEditViewSubscriber()); 
    } 

    // ... 
} 

http://symfony.com/doc/current/cookbook/form/dynamic_form_modification.html

1

mới (cành lá) Template Dont quên {{form_row (form._token)}} khi vẽ biểu mẫu form individualy

<form> 
    {{ form_row(form.fieldToDisabledInEditView) }} 
    {{ form_row(form.field2) }} 
    {{ form_row(form.field3) }} 
    {# ... #} 
    {{ form_row(form._token) }} 

Chỉnh sửa (cành lá) Template Chỉ cần đừng làm cho {{form_row (form.fieldToDisabledInEditView)}} và một lần nữa đừng quên mã thông báo.

<form> 
    {{ form_row(form.field2) }} 
    {{ form_row(form.field3) }} 
    {# ... #} 
    {{ form_row(form._token) }} 
9

Cách tiếp cận này không phải là thanh lịch tại tất cả nhưng tôi sử dụng nó bởi vì rất đơn giản:

EntityController

public function newAction() { 
    $entity = new Entity; 
    $form = $this->createForm(new EntityType, $entity); 
    // ... 
} 
public function editAction() { 
    $entity = new Entity; 
    $form = $this->createForm(new EntityType, $entity); 
    $form->remove('fieldToDisabledInEditView');  
    // ... 
} 
2

Đối với những người tìm kiếm một giải pháp trong Symfony 3 mà không cần tạo kiểu mẫu riêng các lớp (cho cả việc thêm và chỉnh sửa) và không sử dụng các sự kiện biểu mẫu, bạn có thể xác định tùy chọn tùy chỉnh và chuyển nó tới biểu mẫu khi tạo:

Tôi tạo ra một tùy chọn is_edit với giá trị mặc định false trong lớp kiểu dạng:

public function configureOptions(OptionsResolver $resolver) 
{ 
    $resolver->setDefaults(array(
     'data_class' => SomeEntity::class, 
     'is_edit' => false 
    )); 
} 

Bạn có thể truy cập vào tùy chọn này bằng cách sử dụng mảng $options trong phương pháp buildForm của lớp cùng:

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder->add('someField', TextType::class, array(
     'disabled' => $options['is_edit'] 
    )) 
} 

Cuối cùng , bạn có thể ghi đè giá trị mặc định bằng cách chuyển nó vào tạo biểu mẫu:

$someForm = $this->createForm(
    SomeEntityType::class, 
    $someEntity, 
    array('is_edit' => true) 
); 

https://symfony.com/doc/current/form/form_dependencies.html

Các vấn đề liên quan