2013-11-15 89 views
1

我正在嘗試開發一種讓學生從幾個組中選擇課程的表單。它定義如下:Symfony2動態組EntityType字段形式

  • 課程有一個名稱/描述/小時。
  • 課程屬於小組,其名稱/說明/時間限制(例如,您必須從該小組中選擇5個學分,或者只能從該小組中選擇10個小時)
  • 課程組爲組織成一個節目發售,其中可能有其他領域

所以我想讓表格讓學生選擇課程,但課程組織在這些組與指示有多少挑選。信用小時部分將通過自定義驗證規則進行驗證。

這裏是我想到的代碼的一個想法(省略了很多命名空間/原則映射/等)。

的實體的排序是這樣的:

class Offering 
{ 
    // has multiple CourseGroups 
    private $groups; 
} 

class CourseGroup 
{ 
    // which Offering it belongs to 
    private $offering; 
    private $name; 
    private $maxHours; 
} 

class Course 
{ 
    // which CourseGroup it belongs to 
    private $group; 
    private $name; 
    private $hours; 
} 

// User submits an application with chosen courses from multiple groups 
class Application 
{ 
    // ... 
    private $courses; 
} 

// Joins the Applications to Courses (N to N) 
class ApplicationCourse 
{ 
    // which Application 
    private $application; 
    // which Course 
    private $course; 
} 

但我試圖找出如何把這個形式。我不介意將表單綁定到一個數組,然後將它整理出來放入Application

class ApplicationType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder 
      // ...other fields 
     ; 

     // Add the groups of courses to choose 
     $builder->addEventListener(
      FormEvents::PRE_SET_DATA, 
      function(FormEvent $event) use ($offering) { 
       $form = $event->getForm(); 

       // Here I would like to add 1 EntityType per Offering 
       // The EntityType allows the user to select multiple Courses within that group 
       $i = 0; 
       foreach ($offering->groups as $group) { 
        // Maybe add the $group as a static block in the twig template here 
        // Ideally the form should show the group name/description 

        // I'll probably borrow from this class https://github.com/genemu/GenemuFormBundle/blob/master/Form/Core/Type/PlainType.php 

        // This adds a group of checkboxes to select a course from this group 
        $form->add('course_'.$i, 'entity', array(
         'class' => 'Acme\DemoBundle\Entity\Course', 
         'property' => 'name', 
         'multiple' => true, 
         'expanded' => true, 
         'query_builder' => function(EntityRepository $er) use ($group) { 
          // imagine this ia a query that selects all courses in the $group 
          return $er->createGroupCoursesQueryBuilder($group); 
         }, 
        ); 
        $i++; 
       } 
      } 
     ); 
    } 

    public function getName() 
    { 
     return 'task'; 
    } 
} 

最後,我想,看起來像這樣一種形式:

科學:選擇至少4學分

  • [X] SCI100(2小時)
  • [ ] SCI101(2小時)
  • [] SCI102(2小時)

數學:選擇至少4學分

  • [] MTH100(4小時)
  • [X] MTH101(4小時)

{GROUP NAME}:{GROUP說明}

  • [{選擇?}] {課程名稱} {課時}

等等

此方法是否有效?有沒有更好的方法,以便我不必將該表單綁定到數組,然後在驗證後重新組裝它?

+0

這些問題幫助:http://stackoverflow.com/questions/16734480/symfony2-twig-form-field-set-rendered-true和http:// stackoverflow.com/questions/9175593/symfony-2-forms-entity-field-type-grouping – Matt

回答

2

的解決方案是看到這個答案Symfony 2 Forms entity Field Type grouping

我剛剛定製的形式呈現後,其實很簡單。最好的部分是,我得到Symfony窗​​體(數據綁定)的所有有用部分,但我可以完全自定義渲染。

public function buildForm(FormBuilderInterface $builder, array $options) 
{ 
    $builder 
     ->add('courses', 'entity', array(
      'class' => 'MyMainBundle:Course', 
      'property' => 'name', 
      'multiple' => true, 
      'expanded' => true 
     )) 
     ->add('save', 'submit') 
    ; 
} 

在樹枝模板中有一個很酷的技巧來自己渲染它。我確實必須通過課程組。

的技巧是使用{% do form.courses.setRendered %}

{{ form_start(form) }} 
    {{ form_errors(form) }} 

    {% for group in academics.courseGroups %} 
    <section> 
     <h2> 
      {{ group.name }} 
     </h2> 
     <p>{{ group.description }}</p> 

     {% for course in group.courses %} 
     <div class="form-group"> 
      <div class="course"> 
       <div class="checkbox"> 
        <label for="my_mainbundle_application_course_courses_{{ course.id }}"> 
         <input type="checkbox" 
           id="my_mainbundle_application_course_courses_{{ course.id }}" 
           name="my_mainbundle_application_course[courses][]" 
           value="{{ course.id }}" 
           {% if course.id in form.courses.vars.value and form.courses.vars.value[course.id] %}checked="checked"{% endif %}> 
         <span class="name">{{ course.name }}</span> 
         <span class="subject">({{ course.subject }})</span> 
         - 
         <span class="credits">{{ course.credits }} hours</span> 
        </label> 
       </div> 
      </div> 
     </div> 
     {% endfor %} 
    </section> 
    {% endfor %} 

    {% do form.courses.setRendered %} 
    {{ form_row(form.save) }} 

{{ form_end(form) }} 
+0

偉大的幫助選項來設置屬性呈現! – Fuzzzzel