2015-01-14 11 views
6

में एक इकाई के एकाधिक पंक्तियों के साथ एक फ़ॉर्म कैसे बनाएं, पहले मैंने Collection Field Type और How to Embed a Collection of Forms दोनों के लिए दस्तावेज़ पढ़े हैं ... उदाहरण लगभग एक इकाई (कार्य) है जिसमें किसी अन्य इकाई के साथ एक से अधिक संबंध हैं (टैग), और मैं इसे समझता हूं, लेकिन मैं इसे जो अनुकूलित करना चाहता हूं उसे अनुकूलित नहीं कर सकता!Symfony2

यह आसान बनाने के लिए, कहते हैं कि मैं एक टास्क इकाई डालते हैं, इस कार्य इकाई

उपयोगकर्ता और परियोजना की तरह अन्य वस्तुओं के साथ कुछ संबंधों (प्रत्येक कार्य एक उपयोगकर्ता और एक परियोजना हो सकती है) मैं एक बनाना चाहते है फार्म, इस फार्म कार्यों की एक सूची के अंदर, एक मेज से एक पंक्ति में प्रत्येक कार्य के पता चलता है कि जैसे task.title, task.startdate, task.user.name, task.user.company.name जानकारी, task.project.name, और इसमें 2 फ़ील्ड संपादन योग्य हैं, टेक्स्टबॉक्स " विवरण " और चेकबॉक्स" सक्रिय "। आप कई कार्यों को संपादित कर सकते हैं और तालिका के निचले हिस्से में एक बटन का उपयोग करके फ़ॉर्म को सबमिट कर सकते हैं, इसलिए मूल रूप से आप एक लेनदेन में एकाधिक रिकॉर्ड अपडेट करने में सक्षम होना चाहिए (एक फॉर्म बनाने और प्रति पंक्ति सबमिट करने के बजाय बटन प्रति रिकॉर्ड एक रिकॉर्ड अपडेट)।

मैं इस जटिल डिजाइन के साथ कई मुद्दे हैं:

सबसे पहले मैं मुख्य रूप अंदर रूपों का एक संग्रह एम्बेड करने के लिए नमूना का पालन करना चाहता था, इसलिए मुझे लगता है कि एक रूप की तरह होना चाहिए मेरी टास्क के लिए एक प्रपत्र प्रकार बनाया प्रति पंक्ति टास्क के लिए

फार्म प्रकार:

// src/Acme/TaskBundle/Form/Type/TaskType.php 
namespace Acme\TaskBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 

class TaskType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('description', 'text', ['label' => false, 'required' => false, 'attr' => ['placeholder' => 'description']]); 
     $builder->add('active', 'checkbox', ['label' => false, 'required' => false, 'data' => true]); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults(array(
      'data_class' => 'Acme\TaskBundle\Entity\Task', 
     )); 
    } 

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

फार्म मुख्य रूप के लिए प्रकार:

// src/Acme/TaskBundle/Controller/ManageTasksController.php 
namespace Acme\TaskBundle\Controller; 

use Acme\TaskBundle\Entity\Task; 
use Acme\TaskBundle\Form\Type\SaveTaskType; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 

class ManageTasksController extends Controller 
{ 
    public function showListAction(Request $request) 
    { 
     $repository = $this->getDoctrine()->getRepository('ExampleBundle:Task'); 
     $tasks = $repository->findAll(); 

     $taskSaveForm = $this->createForm(new SaveTasksType(['tasks' => $tasks])); 

     return $this->render('AcmeTaskBundle:Task:list.html.twig', array(
      'taskSaveForm' => $taskSaveForm->createView(), 
     )); 
    } 
} 
:

// src/Acme/TaskBundle/Form/Type/SaveTasksType.php 
namespace Acme\TaskBundle\Form\Type; 

use Symfony\Component\Form\AbstractType; 
use Symfony\Component\Form\FormBuilderInterface; 
use Symfony\Component\OptionsResolver\OptionsResolverInterface; 
use Acme\TaskBundle\Form\Type\TaskType.php; 

class SaveTasksType extends AbstractType 
{ 
    public function buildForm(FormBuilderInterface $builder, array $options) 
    { 
     $builder->add('tasksCollection', 'collection', ['type' => new TaskType()]); 
     $builder->add('tasksSubmit', 'submit', ['label' => 'Save']); 
    } 

    public function setDefaultOptions(OptionsResolverInterface $resolver) 
    { 
     $resolver->setDefaults([ 
      'attr' => ['class' => 'form-horizontal'], 
      'method' => 'POST' 
     ]); 
    } 

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

कार्य नियंत्रक फार्म मैं इन फ़ाइलों को बनाया

टास्क प्रपत्र टहनी खाका (सिर्फ संबंधित भाग):

<div class="innerAll"> 
    {{ form_start(taskSaveForm) }} 
    {{ form_errors(taskSaveForm) }} 

    <table class="table table-bordered table-striped table-primary list-table"> 
     <thead> 
      <tr> 
       <th>Task ID</th> 
       <th>Title</th> 
       <th>Start Date</th> 
       <th>User</th> 
       <th>Company</th> 
       <th>Project</th> 
       <th>Description</th> 
       <th>Active</th> 
      </tr> 
     </thead> 
     <tbody> 
      {% for task in taskSaveForm.tasksCollection %} 

       <tr> 
        <td>{{ task.id }}</td> 
        <td><a href="https://localhost/taskid={{ task.id }}">{{ task.title }}</a></td> 
        <td>{{ task.startDate }}</td> 
        <td>{{ task.userName }}</td> 
        <td>{{ task.companyName }}</td> 
        <td>{{ task.projectName }}</td> 
        <td>{{ form_widget(task.description) }}</td> 
        <td>{{ form_widget(task.active) }}</td> 
        <td></td> 
       </tr> 
      {% endfor %} 
     </tbody> 
    </table> 
    <div>{{ form_row(taskSaveForm.tasksSubmit) }}</div> 
    {{ form_end(taskSaveForm) }} 
</div> 

लेकिन एक समस्या है यहाँ है, जब मैं क्वेरी बिल्डर से परिणाम प्राप्त यह उनके में वस्तुओं युक्त सरणियों की गड़बड़ी है, मैं प्राप्त एक

फ़ॉर्म का दृश्य डेटा क्लास Acme \ TaskBundle \ Entity \ Task का उदाहरण होने की उम्मीद है, लेकिन एक (एन) सरणी है। आप "data_class" विकल्प को शून्य या एक व्यू ट्रांसफॉर्मर जोड़कर इस त्रुटि से बच सकते हैं जो एक (एन) सरणी को Acme \ TaskBundle \ Entity \ Task के उदाहरण में बदल देता है।

इस क्वेरी है:

createQueryBuilder() 
    ->select(
      " 
      task.id, 
      task.title, 
      task.startDate, 
      task.description, 
      user.name as userName, 
      company.name as companyName, 
      project.name as projectName, 
      " 
    ) 
     ->from('Acme\TaskBundle\Entity\Task', 'task') 
     ->innerJoin('task.project', 'project') 
     ->innerJoin('task.user', 'user') 
     ->innerJoin('Acme\TaskBundle\Entity\Company', 'company', 'with', 'store.company = company') 
     ->where('task.active = :isActive')->setParameter('isActive', true); 

Soooo, मैं Partial Objects गाइड का इस्तेमाल किया है, तो यह मदद कर सकते हैं देखने के लिए, यह क्वेरी परिणाम में कार्य वस्तु बनाने के लिए मदद करता है और मैं इसे निकालने और यह भेज सकता है बनाने के लिए, लेकिन फिर भी ऐसा लगता है कि शेष रूप बाकी वस्तुओं से अनजान है ...

ठीक है, तो शायद मैं गलत दृष्टिकोण चुन रहा हूं, मुझे यकीन नहीं है! कृपया अगर आपको कोई सुझाव है कि मुझे क्या करना चाहिए, तो यहां एक नोट डालें ... मैं इसके साथ एक सप्ताह से अधिक समय तक संघर्ष कर रहा हूं! आपके समय के लिए आपका अग्रिम धन्यवाद! यहां तक ​​कि यदि आप कोई नोट नहीं डालते हैं, तो भी मैं सराहना करता हूं कि आप मेरे बहुत लंबे प्रश्न पढ़ने में समय बिताते हैं! धन्यवाद! :)

उत्तर

4

यहां एक संभावित समाधान पर शुरुआत है। नीचे दिया गया उदाहरण एक एकल इकाई कौशल लेता है और उन सभी को एक ही पृष्ठ पर प्रस्तुत करता है। मुझे नहीं पता कि क्या इस तकनीक का उपयोग बच्चों की वस्तुओं को जारी रखने के लिए किया जा सकता है। मैं उम्मीद करता हूं कि कोई लौटाए गए डेटा के माध्यम से लूप कर सकता है और आवश्यकतानुसार जारी रहता है।

नीचे दिए गए कोड के परिणामस्वरूप सभी संभावित कौशल की सूची और प्रत्येक सक्षम या सक्षम घोषित करने के लिए एक चेकबॉक्स होता है।

एक नियंत्रक में:

$skills = $em->getRepository("TruckeeMatchingBundle:Skill")->getSkills(); 
    $formSkills = $this->createForm(new SkillsType(), array('skills' => $skills)); 
    ... 
     if ($request->getMethod() == 'POST') { 
      $formSkills->handleRequest($request); 
      foreach ($skills as $existingSkill) { 
       $em->persist($existingSkill); 
      } 
     } 
    ... 
    return ['formSkills' => $formSkills->createView(),...] 

एक टेम्पलेट में:

{% for skill in formSkills.skills %} 
    {{ skill.vars.value.skill }} 
      <input type="hidden" name="skills[skills][{{ loop.index0 }}][skill]" value="{{ skill.vars.value.skill }}"> 
      <input type="checkbox" name="skills[skills][{{ loop.index0 }}][enabled]" 
      {%if skill.vars.value.enabled %}checked="checked"{%endif%} 
{% endfor %} 
+0

क्षमा करें कि मैं वापस आपके पास वापस नहीं आया! मेरे कार्य अनुक्रम बदल गए हैं इसलिए मैं अभी अन्य सामानों पर काम कर रहा हूं ... मैं आपसे वापस आऊंगा और अगर यह काम करता है तो आपको बताएगा! मुझे आपके उत्तर से एक विचार मिला, और मुझे उम्मीद है कि यह काम करता है! समय लेने और उत्तर भेजने के लिए धन्यवाद ... :) – Monica

+0

एक बड़ी देरी के साथ अपने जवाब की जांच के लिए खेद है! आपके उत्तर ने मुझे बहुत मदद की, मैं आपका जवाब स्वीकार करने जा रहा हूं! :) मैं अंतिम संस्करण के साथ बाद में अपना खुद का प्रश्न अपडेट करूंगा! – Monica

+0

देरी पर कोई चिंता नहीं। खुशी हुई यह मदद की। – geoB

0

मैं एक अलग रणनीति का उपयोग करें। मेरी TWIG फ़ाइल मोनिका के सवाल के समान है। लेकिन कुछ लेकिन बहुत उपयोगी मतभेद हैं। यहाँ अपने कोड:

 {{ form_start(form) }} 
    {% for docente in docentes %} 
     Id: <input type="integer" name="{{ docente.id }}" required="required" style="width:30px" value="{{ docente.id }}" readonly> 
     Apellido: <input type="text" name="{{ docente.apellido }}" required="required" style="width: 80px" value="{{ docente.apellido }}" readonly> 
     Nombres: <input type="text" name="{{ docente.nombres }}" required="required" style="width: 80px" value="{{ docente.nombres }}" readonly> 
    Discrecional: <input type="checkbox" name="D{{ docente.id }}" value="{{ docente.discrecional }}" {% if docente.discrecional==1 %}checked{% endif %}> <br> 
     <br> 
    {% endfor %}   
     <input type="submit" value="Grabar" />  
{{ form_end(form) }} 

TWIG फ़ाइल में, मैं "discrecional" क्षेत्र के लिए के रूप में प्रत्येक रिकॉर्ड के लिए एक अलग नाम बनाने के लिए आगे बढ़ें। इससे मुझे नियंत्रक में प्रत्येक रिकॉर्ड की पहचान करने में मदद मिलेगी। ऊपर देखो।

एक बार जब उपयोगकर्ता "सबमिट करें" बटन मैं अपने नियंत्रक फ़ाइल में एक यात्रा करते हैं, जैसा कि नीचे दिखाया प्रेस: ​​

if ($form->isSubmitted() && $form->isValid()) {  
      $i=0; 
       foreach ($defaultData as $value) { 
        $data2= array('id' =>$request->request->get($defaultData[$i]['id']), 
        'discrecional' =>$request->request->get('D'.$defaultData[$i]['id'])); 

        if (($request->request->get('D'.$defaultData[$i]['id'])== '0' and $defaultData[$i]['discrecional']=='0') or 
         ($request->request->get('D'.$defaultData[$i]['id'])== NULL and $defaultData[$i]['discrecional']=='1'))  
        { 
        $em->getRepository('BackendBundle:Docentes')->findDocenteFiltId2($data2); 
        } 
        $i=$i+1; 
       } 

लेकिन रजिस्टरों की अद्यतन, कि के माध्यम से अपने भंडार फ़ाइल में किया जाता है एक काम है नियंत्रक फ़ाइल में इसे करने के बजाय, UPDATE का उपयोग कर एक क्वेरी। अनावश्यक प्रश्नों और सर्वर अधिभार से बचने के लिए, मैं केवल उन अभिलेखों का अद्यतन करता हूं जो पहले बदल चुके हैं। उदाहरण में, मेरे नियंत्रक में निम्न पंक्तियां जांचती हैं कि रिकॉर्ड में कोई बदलाव आया है (मेरे मामले में, मैं सिर्फ "विवेकाधीन" नामक फ़ील्ड को संपादित कर रहा हूं। यदि फ़ील्ड बदल गया है, तो मैं क्वेरी और अपडेट को कॉल करता हूं रिकॉर्ड):

if (($request->request->get('D'.$defaultData[$i]['id'])== '0' and $Data[$i]['discrecional']=='0') or 
        ($request->request->get('D'.$defaultData[$i]['id'])== NULL and $defaultData[$i]['discrecional']=='1'))  
       { 
       $em->getRepository('BackendBundle:Docentes')->findDocenteFiltId2($data2); 
       } 

मेरे पूरा नियंत्रक फ़ाइल यहाँ है:

public function discrecionalAction(Request $request) 
{ 
    $em = $this->getDoctrine()->getManager();  
    $defaultData= $em->getRepository('BackendBundle:Docentes')->buscarDocentesActivos2(); 


// construimos un formulario "vacío" sin campos definido 
      $form = $this->createFormBuilder($defaultData); 
     $form = $form->getForm(); 

      $form->handleRequest($request);  


      if ($form->isSubmitted() && $form->isValid()) { 


      $i=0; 
       foreach ($defaultData as $value) { 
        $data2= array('id' =>$request->request->get($defaultData[$i]['id']), 
        'discrecional' =>$request->request->get('D'.$defaultData[$i]['id'])); 

        if (($request->request->get('D'.$defaultData[$i]['id'])== '0' and $defaultData[$i]['discrecional']=='0') or 
         ($request->request->get('D'.$defaultData[$i]['id'])== NULL and $defaultData[$i]['discrecional']=='1'))  
        { 
        $em->getRepository('BackendBundle:Docentes')->findDocenteFiltId2($data2); 
        } 
        $i=$i+1; 
       } 

    return $this->redirectToRoute('docentes_discrecional'); 

       }   


     return $this->render('docentes/discrecional.html.twig', array(
       'docentes' =>$defaultData, 
     'form' => $form->createView())); 
} 

मेरे पूरा पहले भंडार क्वेरी यहां है:

public function buscarDocentesActivos2() 
{ 


     $fields = array('d.id', 'd.apellido', 'd.nombres', 'd.discrecional'); 
$query = $this->getEntityManager()->createQueryBuilder(); 
     $query 
      ->select($fields) 
      ->from('BackendBundle:Docentes', 'd') 
      ->where('d.activo=true') 
      ->orderBy('d.apellido, d.nombres');  

     $consulta = $query->getQuery()->getResult(); 

     return $consulta; 
    } 

मेरे पूरा अंतिम भंडार के साथ क्वेरी अद्यतन समारोह यहां है:

public function findDocenteFiltId2($filtro) 
{ 

if (is_null($filtro['discrecional'])){ 
    $discrec= '0'; 
}; 

if ($filtro['discrecional']=='0'){ 
    $discrec= '1'; 
}; 

$em = $this->getEntityManager(); 

    $consulta = $em->createQuery(' 
     UPDATE BackendBundle:Docentes d 
     SET d.discrecional = :disc 
     WHERE d.id = :idver 
    '); 

    $consulta->setParameters(array(

    'idver' => $filtro['id'], 
    'disc' => $discrec,  
     )); 
     return $consulta->getArrayResult(); 

}