php - How to persist a form to a database, NOT entity, in Symfony2 -


i'm rebuilding web app using symfony2. want users update specific records have on our mysql database. however, users aren't confident computer users , don't way web application (in current form) works. therefore, ui/ux perspective, decided use 2 forms edit specific data instead of current 1 form users don't like.

the mysql database table in question holds numerous fields of information, such personal details , other information relevant them. forms split reflect this, idea 1 form updates personal details, , 1 form updates rest, user doesn't have deal 1 long form.

at moment though, when go use 1 form, error:

the class 'symfony\component\form\form' not found in chain configured namespaces during form submission

this error solved in question. however, it's left me problem. currently, because i've split form in two, i'm unable save data database. can overcome using 1 form, goes against wishes of users of database. furthermore, know it's entirely possible use 2 or more forms add specific data single database i've done before, not in symfony.

does know, or have suggestion, how can overcome this? changing database out of question, due sheer volume of current data on there.

update

here missing view, controller , form files.

view.html.twig

<!-- modal windows: edit instructor personal details --> <div id="editpersonal" style="display:none;">     <div class="modal-head">         <h2>edit personal details for: <font-color="red !important">{{instructor.firstname}} {{instructor.surname}}</font></h2>     </div>     <div class="modal-body">         <form action="#" method="post" {{ form_enctype(ipde) }} id="editpersonaldetails" class="modaledit">         <table class="modalform-col1">             <tbody>                 <tr class="hidden">                     <th>{{ form_label(ipde.id, 'id*', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.id) }}                         {{ form_widget(ipde.id, { 'attr': {'class': 'textfield'}}) }}                     </td>                 </tr>                 <tr>                     <th>{{ form_label(ipde.firstname, 'first name*', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.firstname) }}                         {{ form_widget(ipde.firstname, { 'attr': {'class': 'text'}}) }}                     </td>                 </tr>                 <tr>                     <th>{{ form_label(ipde.surname, 'surname*', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.surname) }}                         {{ form_widget(ipde.surname, { 'attr': {'class': 'text'}}) }}                     </td>                 </tr>                 <tr>                     <th>{{ form_label(ipde.address1, 'address line 1*', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.address1) }}                         {{ form_widget(ipde.address1, { 'attr': {'class': 'text'}}) }}                     </td>                 </tr>                 <tr>                     <th>{{ form_label(ipde.address2, 'address line 2', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.address2) }}                         {{ form_widget(ipde.address2, { 'attr': {'class': 'text'}}) }}                     </td>                 </tr>                 <tr>                     <th>{{ form_label(ipde.town, 'town*', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.town) }}                         {{ form_widget(ipde.town, { 'attr': {'class': 'text'}}) }}                     </td>                 </tr>                 <tr>                     <th>{{ form_label(ipde.county, 'county*', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.county) }}                         {{ form_widget(ipde.county, { 'attr': {'class': 'text'}}) }}                     </td>                 </tr>                 <tr>                     <th>{{ form_label(ipde.postcode, 'postcode*', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.postcode) }}                         {{ form_widget(ipde.postcode, { 'attr': {'class': 'text'}}) }}                     </td>                 </tr>                 <tr>                     <th>{{ form_label(ipde.email, 'email*', { 'attr': {'class': 'title'} }) }}</th>                     <td>                         {{ form_errors(ipde.email) }}                         {{ form_widget(ipde.email, { 'attr': {'class': 'text'}}) }}                     </td>                 </tr>             </tbody>         </table>     </div>     <div class="modal-footer">         <div class="modal-placeright">             <a href="#close" rel="modal:close" class="closebutton">close without saving</a>             <input type="submit" value="save changes" id="savebuttonpr" class="savebutton" />             {{ form_rest(ipde) }}          </div>     </div> </div> 

defaultcontroller.php

<?php  namespace pcuk\instructorbundle\controller;  use symfony\bundle\frameworkbundle\controller\controller; use pcuk\instructorbundle\form\ipdetype; use pcuk\instructorbundle\form\irtype; use pcuk\instructorbundle\form\batype; use symfony\component\httpfoundation\request;  class defaultcontroller extends controller {      public function viewaction($instructor, request $request)     {         // database connection         $insrep = $this->getdoctrine()->getmanager();          // instructor entity form use         $instructorq = $insrep->getrepository('instructorbundle:mapinstructors')->find($instructor);          // shared branches entity form use         $instructors = $insrep->getrepository('instructorbundle:mapinstructorshared')->find($instructor);          // generate form edit instructor personal details         $ipde = $this->createform( new ipdetype(), $instructorq);          // handle form submission edit instructor personal details         if ($request->getmethod() == 'post') {             $ipde->bind($request);              if ($ipde->isvalid()) {                 // perform action, such saving task database                  //if ($this->request->isxmlhttprequest()){                        //return data ajax requires.                 //}                 $em = $this->getdoctrine()->getmanager();                 $em->persist($ipde);                 $em->flush();                   return $this->redirect($this->generateurl('task_success'));             }         }          // generate form edit instructor records         $ir = $this->createform( new irtype(), $instructorq);          // generate form edit instructor records         $ba = $this->createform( new batype(), $instructors);          // return data view         return $this->render('instructorbundle:default:view.html.twig', array(             'ipde' => $ipde->createview(),             'ir' => $ir->createview(),             'ba' => $ba->createview()         ));     } } 

ipdetype.php - personal details form

<?php // src/pcuk/instructorbundle/form/type/ipdetype.php // handle forms instructor personal details form namespace pcuk\instructorbundle\form;  use doctrine\orm\entityrepository; use symfony\component\form\form; use symfony\component\form\abstracttype; use symfony\component\form\formbuilderinterface; use symfony\component\form\filefield;  class ipdetype extends abstracttype {     public function buildform(formbuilderinterface $builder, array $options)     {         $builder->add('id', 'integer', array('required'=>false));         //personal details         $builder->add('firstname', 'text', array('required'=>false));         $builder->add('surname', 'text', array('required'=>false));         $builder->add('address1', 'text', array('required'=>false));         $builder->add('address2', 'text', array('required'=>false));         $builder->add('town', 'text', array('required'=>false));         $builder->add('county', 'text', array('required'=>false));         $builder->add('postcode', 'text', array('required'=>false));         $builder->add('email', 'text', array('required'=>false));         $builder->add('phone', 'text', array('required'=>false));         $builder->add('mobile', 'text', array('required'=>false));         $builder->add('notes', 'text', array('required'=>false));     }      public function getname()     {         return 'ipde';     } } 

irtype.php - other information form

<?php // src/pcuk/instructorbundle/form/type/irtype.php // handle forms instructor records form namespace pcuk\instructorbundle\form;  use doctrine\orm\entityrepository; use symfony\component\form\form; use symfony\component\form\abstracttype; use symfony\component\form\formbuilderinterface; use symfony\component\form\filefield;  class irtype extends abstracttype {     public function buildform(formbuilderinterface $builder, array $options)     {         $builder->add('id', 'integer', array('required'=>false));         $builder->add('primaryarea', 'integer', array('required'=>false));         $builder->add('primarybranch','entity', array('class'=>'pcuk\instructorbundle\entity\mapbranches', 'property'=>'branchname' ));         $builder->add('begin', 'date', array('required'=>false));         $builder->add('lastcrb', 'date', array('required'=>false));         $builder->add('latestcpd', 'date', array('required'=>false));         $builder->add('preferredlevel','entity', array('class'=>'pcuk\instructorbundle\entity\mapinstructorlevels', 'property'=>'name' ));         $builder->add('preferreddiscipline','entity', array('class'=>'pcuk\instructorbundle\entity\mapinstructorlevels', 'property'=>'name' ));         $builder->add('currentlevel','entity', array('class'=>'pcuk\instructorbundle\entity\mapinstructorlevels', 'property'=>'name' ));         $builder->add('bhs', 'checkbox', array('required'=>false));         $builder->add('visiting','entity', array('class'=>'pcuk\instructorbundle\entity\mapinstructorvis', 'property'=>'name' ));     }      public function getname()     {         return 'ir';     } } 

update: 29/04/13 following james_t's advice, split entity in two, 1 each of forms respectively. however, original error still occurs.

i've created new action in controller, , because split entity hasn't fixed issue, reverted using single entity. controller looks follows:

viewaction public function viewaction($instructor, request $request) { // database connection $insrep = $this->getdoctrine()->getmanager();

// ipde entity form use $instructoripde = $insrep->getrepository('instructorbundle:mapinstructors')->find($instructor);  // generate form edit instructor personal details $ipde = $this->createform( new ipdetype(), $instructoripde);  // ir entity form use $instructorir = $insrep->getrepository('instructorbundle:mapinstructors')->find($instructor);  // generate form edit instructor records $ir = $this->createform( new irtype(), $instructorir);  // shared branches entity form use $instructorba = $insrep->getrepository('instructorbundle:mapinstructorshared')->find($instructor);  // generate form edit instructor records $ba = $this->createform( new batype(), $instructorba);  // return data view return $this->render('instructorbundle:default:view.html.twig', array(     'pagename' => $iname . ' - instructors',      'ipde' => $ipde->createview(),     'ir' => $ir->createview(),     'ba' => $ba->createview(),         'iid' => $instructor )); 

}

ipdeaction

public function ipdeaction($instructor, request $request) { // database connection $insrep = $this->getdoctrine()->getmanager();

// ipde entity form use $instructoripde = $insrep->getrepository('instructorbundle:mapinstructors')->find($instructor);  // generate form edit instructor personal details $ipde = $this->createform( new ipdetype(), $instructoripde);  // handle form submission edit instructor personal details if ($request->getmethod() == 'post') {     $ipde->bind($request);      if ($ipde->isvalid()) {         // perform action, such saving task database          //if ($this->request->isxmlhttprequest()){                //return data ajax requires.         //}         $em = $this->getdoctrine()->getmanager();         $em->persist($ipde);         $em->flush();          $params = array(             'instructor'  => $instructor,         );          return $this->redirect($this->generateurl('instructor_viewinstructor', $params));     } } 

}

i've fixed updated view.html.twig file this:

<form action="#" method="post" {{ form_enctype(ipde) }} id="editpersonaldetails" class="modaledit"> 

to this:

<form action="{{ path('instructor_viewinstructor_ipde', {'instructor' :iid}) }}" method="post" {{ form_enctype(ipde) }} id="editpersonaldetails" class="modaledit"> 

my routing.yml file looks now:

instructor_viewinstructor:     pattern:  /instructors/view/{instructor}     defaults: { _controller: instructorbundle:default:view }  instructor_viewinstructor_ipde:     pattern:  /instructors/view/{instructor}/ipde     defaults: { _controller: instructorbundle:default:ipde }     requirements:         _method:  post 

it seems bit odd me fact generating 3 forms (1 of them twice same entity, $ir , $ipde). error getting related that.

i've done before , can share guidelines you:

  • you don't need separate entity each form, need separate form entity. don't take me wrong, work either way, doesn't make difference. in code using twice connections required.

  • you passing 3 forms view rendering one, why?, unless use ajax, doesn't make sense.

let me describe way go:

  1. create entities application needs (generally 1 per table), split them that's necessary when working more complex logic (i.e. different kind of permission / ownership on same row different users, though kind of smelly).

  2. if want use validation component make sure getting data, use validation groups, 1 group each form want build).

  3. create form type each form want build. sounds kind of obvious. can have many form types entity want. on each form, include fields interested in.

  4. create view each 1 of forms. straight forward.

  5. here things change most. need, have one controller action per form, don't mix them, save nothing. each controller action should:

    • load entity interested in
    • build form of correct type.
    • if get, render just one form , return.
    • if post, bind request, save , stuff.

basically workflow like:

  • the user wants edit entity id=x,
  • you call controller handles data want edit , return form.
  • the user submits form , save data. play redirect chain both parts of process, redirect url of second controller handles extended information. if chaining, might find useful use flash messages let user know information saved.

hope helps.


Popular posts from this blog

How to calculate SNR of signals in MATLAB? -

c# - Attempting to upload to FTP: System.Net.WebException: System error -

ios - UISlider customization: how to properly add shadow to custom knob image -