Cibul Tech Blog - Fiddling with PHP, javascript and things

Embedded forms with symfony 1.4 and jQuery

ShareThis

How to implement a single interface to insert multiple entries linked by one-to-many relations…

I’ve been looking recently for a way to build a form that would allow the input of data (edition or adding new data) into multiple related objects. Turns out the way to do this in symfony is to use embedded forms and this what this post is about. I am not an expert in symfony nor in jQuery so if find better ways to do some of the things described here I’ll be happy to read your comments.

We’ll build a listing of events which will be editable to the user. Each event has one or more occurrences (a place and a time). Forms shown should allow the user to edit each event and their related occurrences under the same interface plus leaving them the possibility to add new occurrences if needed.

We will do this in 5 steps:

  1. Setting up the project: we’ll create a symfony project and mysql database
  2. Editing Events: we’ll create a form where both events and occurrences can be edited using embedded forms
  3. Adding new occurrence fields: we’ll add the functionality to add more blank occurrence fields using jQuery Ajax functions
  4. Removing new occurrence fields: still using jQuery, we’ll allow the user to remove blank occurrence fields
  5. Creating a new Event: We’ll modify the form template slightly to allow the user to add more events to the list

Ok, this should take a little while so let’s get started!

1. Setting up the project and showing the index page

We start by setting up a symfony project and building a database based on the following schema and fixtures:

The schema:

#config/doctrine/schema.yml
Event
:
  columns
:
    id
:
      type
: integer
      primary
: true
      autoincrement
: true
    title
:
      type
: string(255)
      notnull
: true
  relations
:
    Occurrences
:
      type
: many
      class
: Occurrence
      local
: id
      foreign
: event_id
      onDelete
: CASCADE

Occurrence
:
  columns
:
    id
:
      type
: integer
      primary
: true
      autoincrement
: true
    location
:
      type
: string(255)
      notnull
: true
    date
:
      type
: date
      notnull
: true
    event_id
:
      type
: integer
      notnull
: true
  relations
:
    Event
:
      type
: one
      local
: event_id

… and the fixtures:

#data/fixtures/fixtures.yml
Event
:
  apero_geant
:
    title
: Apero Geant
  rugby_night
:
    title
: Rugby Night

Occurrence
:
  apero_geant1
:
    Event
: apero_geant
    location
: Marseille, France
    date
: '2009-08-29'
  apero_geant2
:
    Event
: apero_geant
    location
: Nantes, France
    date
: '2009-11-10'
  apero_geant3
:
    Event
: apero_geant
    location
: Rennes, France
    date
: '2010-03-25'
  rugby_night1
:
    Event
: rugby_night
    location
: Yvetot, France
    date
: '2010-03-20'

After generating a frontend app, we can create an ‘event’ module by just adding the event/actions and event/templates directories under the modules directory of the app.

In an action.class.php file, we create a first index action that sends a list of events to an indexSuccess.php template.

<?php // apps/frontend/modules/event/actions/actions.class.php

  class eventActions extends sfActions{

    public function executeIndex(sfWebRequest $request){
      $this->events = Doctrine_Core::getTable('Event')->findAll();
    }

  }

To make things simple, we’ll set the index action as default in the routing, removing the default content.

#app/frontend/config/routing.yml
homepage
:
  url
:  /
  param
: { module: event, action: index }

The occurrences are listed under each event in the indexSuccess.php template:

<!--apps/frontend/modules/templates/indexSuccess.php -->
<h2>Events Index</h2>
<?php foreach($events as $event): ?>
<div class="event-item">
  <h3><?php echo $event->getTitle() ?></h3>
  <ul>
    <?php foreach($event->getOccurrences() as $occurrence): ?>
      <li><?php echo $occurrence->getDate()?> - <?php echo $occurrence->getLocation() ?></li>
    <?php endforeach;?>
  </ul>
</div>
<?php endforeach; ?>

There, the first step is done and the project is set up with a default index page showing the events and their occurrences

2 – Editing existing events & their occurrences

Now we have to setup the embedded form structure

We want to be able to edit any of the listed events and their occurrences in the same form. Let’s start by creating an edit action and associated template and link it to the index page. We’ll start simple and setup a standard form that will allow us to update the title field of the event. Once this is running we will start working with embedded forms to add the possibility to edit the related occurrences as well.

To get things working we need to create an edit action and template to launch the edition form, a submit action for updating the database when the form has been filled, and we’ll add some links to the index page to be able to access the edit menu for each event.

  • Let’s start with the executeEdit() action: It simply creates a form and sends it to the editSuccess.php template
  • // apps/frontend/modules/event/actions/actions.class.php

        public function executeEdit(sfWebRequest $request){
          $this->forward404Unless($event = Doctrine::getTable('Event')->find(array($request->getParameter('id'))), sprintf('Event does not exist (%s).', $request->getParameter('id')));
          $this->form = new EventForm($event);
        }
  • The template editSuccess(): It lays out the form and has it ready to send the result to the submit action
  • <!--apps/frontend/modules/templates/editSuccess.php-->
    <h2>Edit Event</h2>

    <form action="<?php echo url_for('@submit') ?>" method="post">
      <?php echo $form->renderHiddenFields() ?>
      <?php echo $form['title']->renderLabel()?> <?php echo $form['title']->renderError()?> <?php echo $form['title'] ?>
      <input type="submit" value="Save" />
    </form>

    <a href="<?php echo url_for('@homepage')?>">Back to index</a>
  • The routing has to be updated with both edit and submit routes:
  • #app/frontend/config/routing.yml
    edit
    :
      url
    : /edit
      param
    : { module: event, action: edit }

    submit
    :
      url
    : /submit
      param
    : { module: event, action: submit }
  • And the submit action, executeSubmit(): it extracts from the request the values passed on by the form, gets the event object based on the extracted id, makes a form from it, binds it with the request data and updates the database. It is important here to focus on what binding a form means: basically, when the form is created from an event object generated from the database, the values stored are the ones of the database, not the ones input by the user in the previous page; these are still stored in the request object. The bind action consists in taking the values of the request and using them to update the freshly created form, checking the validity of the data in the process, as per the form’s rules. If the validity is confirmed, the database is updated by the save method.
  • // apps/frontend/modules/event/actions/actions.class.php

        public function executeSubmit(sfWebRequest $request){
          $tainted_values = $request->getParameter('event');
          $event = Doctrine::getTable('Event')->find($tainted_values['id']);

          $this->form = new EventForm($event);

          if ($request->isMethod('post') && $this->form->bindAndSave($tainted_values))
            $this->redirect('@homepage');

          $this->setTemplate('edit');
        }
  • The index should have link for each event to allow users to show the edit page, add this under the event title:
  • <!--apps/frontend/modules/templates/indexSuccess.php -->

    <a href="<?php echo url_for('event/edit?id='.$event->getId())?>">edit event</a>

    Now you should have a straightforward way of updating event titles. But here comes the tricky part: how to updated the data of the occurrences of the event as well? This can actually be done easily by fiddling with the event form and embedding occurrence forms to it. But we only want to embed the occurrences which are linked to the event. A method serves that purpose and can be used to do just that in one line: embedRelation(). This method basically takes all related objects and generates the corresponding embedded forms. Enough bla bla, lets update the EventForm class with it:

    <?php //lib/form/doctrine/EventForm.class.php

    class EventForm extends BaseEventForm
    {
      public function configure()
      {
        $this->embedRelation('Occurrences');
      }
    }

    Open the OccurrenceForm.class.php and unset the variables that should’nt be in the form:

    <?php //lib/form/doctrine/OccurrenceForm.class.php

    class OccurrenceForm extends BaseOccurrenceForm
    {
      public function configure()
      {
        unset($this['event_id']);
      }
    }

    Now update as well the editSuccess.php template to show the occurrences of an event when they exist… add this bit under the event title fields:

    <!--apps/frontend/modules/templates/editSuccess.php-->
    <ul>
        <?php foreach ($form['Occurrences'] as $occurrence):?>
        <li>
          <?php echo $occurrence['date']->renderLabel() ?>  <?php echo $occurrence['date']->renderError() ?>
          <?php echo $occurrence['date'] ?>
           -
          <?php echo $occurrence['location']->renderLabel() ?>  <?php echo $occurrence['location']->renderError() ?>
          <?php echo $occurrence['location'] ?>
        </li>
        <?php endforeach ?>
      </ul>

    There. Your form allows you to update the occurrences as well.

    3 – Adding new occurrence field sets with jQuery

    But what if you want to add new occurrences to your event? Wouldn’t it be swell to have some neat way to add new occurrence fields as you please now wouldn’t it?

    Sure it would. And we’ll make it happen using some ajax functions with jQuery.

    To do this, we’ll add some javascript mechanisms on the edition page that will consist in querying the server for some bits of forms, and once receive, appending them to the rest of the page without the need for a refresh. On the server side, a new action will handle the ajax request and re-assemble the forms to send the right piece back.

    We start by adding the jquery library (I’m using jquery 1.4.2) to the js folder as well as an empty js file (eventform.js). In the layout.php of the frontend app we add a reference to each file in the header

    <!--app/frontend/template/layout.php-->
    ...
        <?php include_stylesheets() ?>
        <?php use_javascript('jquery-1.4.2.min.js') ?>
        <?php use_javascript('eventform.js') ?>
        <?php include_javascripts() ?>
    ...

    Now in the editSuccess.php templage, we’ll add a button (a link actually) after the occurrence list. We’ll bind it with javascript behavior to add the new fields.

    <!--apps/frontend/modules/templates/editSuccess.php-->
    ...
    </ul>
    <a id="addoccurrence" href="#">Add an occurrence</a>

    In the javascript file (eventform.js), add the following:

    /* web/js/eventform.js */
    newfieldscount = 0;

    function addNewField(num){
      return $.ajax({
        type: 'GET',
        url: '/add?num='+num,
        async: false
      }).responseText;
    }

    $(document).ready(function(){
      $('#addoccurrence').click(function(e){
        e.preventDefault();
        $('ul').append(addNewField(newfieldscount));
        newfieldscount = newfieldscount + 1;
      });
    });

    Everytime the page element with #addoccurrence as id will be clicked, a new field will be fetched through an ajax request and be appended to the occurrence list. The missing piece now is the processing on the server side of the request. First thing is to update the routing by adding the route we describe in the javascript file…

    #app/frontend/config/routing.yml
    add
    :
      url
    : /add
      param
    : { module: event, action: add }

    … and add the corresponding action, which should work only when the request comes from an XmlHttpRequest.

    // apps/frontend/modules/event/actions/actions.class.php

        public function executeAdd(sfWebRequest $request){
          $this->forward404unless($request->isXmlHttpRequest());
          $number = intval($request->getParameter("num"));

          $this->form = new EventForm();

          $this->form->addNewFields($number);

          return $this->renderPartial('addNew',array('form' => $this->form, 'number' => $number));
        }

    The action calls a method of the EventForm class that will add the number of occurrences needed to replicate the current structure of the form displayed.

    //lib/form/doctrine/EventForm.class.php

      public function addNewFields($number){
        $new_occurrences = new BaseForm();

        for($i=0; $i <= $number; $i+=1){
          $occurrence = new Occurrence();
          $occurrence->setEvent($this->getObject());
          $occurrence_form = new OccurrenceForm($occurrence);

          $new_occurrences->embedForm($i,$occurrence_form);
        }

        $this->embedForm('new', $new_occurrences);
      }

    As you can see, Forms behave as arrays. When you need to create a form with multiple embedded forms, you first create an array of form and you embed in it all the forms that you need. Once you’re done, you embedd that form array into your main form.

    Now we need to create the partial that contains the html to send back to the ajax call. It should contain only the last embedded form (the one to be added).

    //apps/frontend/modules/event/templates/_addNew.php
    <li>
      <?php echo $form['new'][$number]['date']->renderLabel() ?>  <?php echo $form['new'][$number]['date']->renderError() ?>
      <?php echo $form['new'][$number]['date'] ?>
       -
      <?php echo $form['new'][$number]['location']->renderLabel() ?>  <?php echo $form['new'][$number]['location']->renderError() ?>
      <?php echo $form['new'][$number]['location'] ?>
    </li>

    One last thing: now, when the event form is submitted and received by the submit action, the action creates a form to which the data in the request will be bound (the data you just submitted). But before this can happen, the structure of the form needs to match the data received: the number of new embedded forms should be the same as the number submitted. The bind method in the EventForm does just that: it recreates the structure of the request data in the created form before the form binding is done.

    //lib/form/doctrine/EventForm.class.php

      public function bind(array $taintedValues = null, array $taintedFiles = null){

        $new_occurrences = new BaseForm();
        foreach($taintedValues['new'] as $key => $new_occurrence){
          $occurrence = new Occurrence();
          $occurrence->setEvent($this->getObject());
          $occurrence_form = new OccurrenceForm($occurrence);

          $new_occurrences->embedForm($key,$occurrence_form);
        }

        $this->embedForm('new',$new_occurrences);

        parent::bind($taintedValues, $taintedFiles);
      }

    4 – Removing new occurrence field sets with jQuery

    What about removing added empty occurrences? This is less tricky as it does not require any server side processing. All we will need to do now is add a remove link for each of the new occurrence fields and add behavior to them.

    First things first, the remove link has to be added in the addNew.php partial:

    <!--apps/frontend/modules/event/templates/_addNew.php-->
    ...
    <a class="removenew" href="#">Remove</a>
    </li>

    Now some behavior needs to be bound to it. One small thing: as this link is loaded through javascript, the behavior needs to be loaded after the item has been loaded.

    We have to update the eventform.js with a removeNew function which will be launched everytime the remove button is pressed.

    /* web/js/eventform.js */

    var removeNew = function(){
      $('.removenew').click(function(e){
        e.preventDefault();
        $(this).parent().remove();
      })
    };

    Still in the javascript file, update the #addoccurrence button behavior:

    /* web/js/eventform.js */

    $(document).ready(function(){
      $('#addoccurrence').click(function(e){
        e.preventDefault();
        $('ul').append(addNewField(newfieldscount));
        newfieldscount = newfieldscount + 1;
        $('.removenew').unbind('click');
        removeNew();
      });
    });

    Et Voila.

    5 – Adding new events

    Now one last thing we want to do: add a link to the index page to display a form for adding new events. When a new event is created, it should at least contain one occurrence. This should be simple: we will re-use the indexSuccess.php template by modifying it slightly and add a new action.

    We can create the link in the index page (at the end):

    <!--apps/frontend/modules/templates/indexSuccess.php -->

    <a href="<?php echo url_for('@new')?>">Add an Event</a>

    Update the routing.

    #app/frontend/config/routing.yml
    new
    :
      url
    : /new
      param
    : { module: event, action: new }

    … and create the executeNew action

        public function executeNew(sfWebRequest $request){
          $event = new Event();
          $this->form = new EventForm($event);

          $this->form->addNewFields(0);

          $this->setTemplate('edit');
        }

    … and as well update the editSuccess.php template so that one new field is readily available (and non removable) when the form is for a new event. Add this just after the ul tag:

    <!--apps/frontend/modules/templates/editSuccess.php-->
        <?php if ($form->getObject()->isNew()): ?>
        <script type="text/javascript">newfieldscount = 1;</script>
          <li>
            <?php echo $form['new'][0]['date']->renderLabel() ?>  <?php echo $form['new'][0]['date']->renderError() ?>
            <?php echo $form['new'][0]['date'] ?>
             -
            <?php echo $form['new'][0]['location']->renderLabel() ?>  <?php echo $form['new'][0]['location']->renderError() ?>
            <?php echo $form['new'][0]['location'] ?>
          </li>
        <?php endif ?>

    I’ll leave you to do something similar with the title to replace “Edit Event” with “New Event”

    And we’re done! This should allow you to edit and add events and their occurrences, using embedded forms and dynamic functions to add more occurrences. I hope this will be useful for you. Again, your input and comments are welcome.

    By the way, you can download the code here.

    Thanks to Nacho and Nicolas, their posts were very useful. You can find find another interesting tutorial on embedded forms here.

    Tags: , ,

    41 Responses to “Embedded forms with symfony 1.4 and jQuery”

    Laurent April 16th, 2010 @ 07:44

    Ca prend form si je peux me permettre :)
    Et puis ca me fais un tutorial!

    thibault April 16th, 2010 @ 08:01

    Very nice and complete article. The next step : writing a plugin ?

    kaore April 16th, 2010 @ 08:37

    Thanks, good idea for the plugin, I definitely need to spend some time on those as well…

    Victor May 10th, 2010 @ 11:09

    Hi!, your code has a strange behaviour when you clean all the required fields on an Ocurrence, hit “Save” and then hit “Add an ocurrence”, is there a solution for this?

    kaore May 10th, 2010 @ 12:42

    Hi Victor, once you hit save, it should redirect to the index. What exactly happens on your side?

    Victor May 11th, 2010 @ 02:27

    It works well, but adding a new “ul” inside a “li” makes all the web page “ul”‘s embeds with the added ocurrence, I solved that adding “id=’#temp’” to the “ul” and changing the eventform.js to point to that id.
    Another question: i used another schema with a 1 to many relationship and try to use your code, all works fine except when i hit the submit button, and receive this message “SQLSTATE[23000]: Integrity constraint violation: 1048 Column ‘temp_id’ cannot be null”. temp_id is the one to many relationship key, where in your code did you bind that field?

    kaore May 12th, 2010 @ 19:04

    Your temp_id is not set when you try to save the data in the database. In the tutorial example, the parent id in the children entries is set in the modified bind function ( $occurrence->setEvent($this->getObject()); )… I hope this helps.

    stwe May 13th, 2010 @ 04:13

    if I only edit the form, i get a warning that the “new” index is undefined in function “bind”. I solve the problem with “isset”. Who else has this problem?

    kaore May 15th, 2010 @ 21:36

    In my case when you’re in edit it just jumps the loop when it doesn’t find the “new” index. You must get a notice level error which in my config is just ignored. But you are right, using an isset test is cleaner. This is described a bit in the php documentation: http://php.net/manual/en/language.types.array.php

    Nelson June 22nd, 2010 @ 07:28

    @victor… I fell in the same issue, but your solution does not work at all with my case (I’m using Symfony 1.4.5) I think the problem is in the routing… using “#” as url in the href field is changed with “edit?id=1″ by symfony and that result in the whole form being embedded into the UL tag… but defining a empty route does not work either. I would like to fix that because this aproach looks nice.

    Nelson June 25th, 2010 @ 23:11

    Finally I found the error, in the addNewField function (eventform.js) I wrote the url parameter using the module name:

    url: ‘/event/add?num=’+num,

    the correct way is:

    url: ‘/add?num=’+num,

    The curious thing is that I don’t need to put any ID in the UL element, in order to append LI element to it… in fact, the example works just fine the way it is…

    Anyway, I did some a little improvement to the editSuccess template: instead to write the occurrences widgets twice (one for the editSuccess template and another for the addNew partial) use include_partial to call it in both situations:

    Replacing this:

    getObject()->isNew()): ?>
    newfieldscount = 1;

    renderLabel() ?> renderError() ?>

    -
    renderLabel() ?> renderError() ?>

    By this:

    getObject()->isNew()): ?>
    newfieldscount = 1;
    $form, ‘number’ => 0)) ?>

    sewid July 9th, 2010 @ 19:13

    Hi!

    I’ve got a question concerning the validation check. Your foreach iterates over all $form['Occurrences'], but if there is an validation error, new fields are contained in $form['new'], am I right?

    So, the new fields won’t get displayed…

    There must be a second iteration for $form['new'], or am I wrong?

    Best regards,
    Sebastian

    kaore July 24th, 2010 @ 18:00

    You are right, basically they exist the $form['new'] embedded forms should be displayed if they are erroneous. Adding this bit of code in the template after the $form['Occurrences'] does the trick:

    < ?php if(isset($form['new'])): ?>
    < ?php foreach ($form['new'] as $occurrence):?>
    [same bit of code as other loop]
    < ?php endforeach ?>
    < ?php endif; ?>

    Jasper August 2nd, 2010 @ 22:48

    Thanks for the amazing tutorial!

    Instead of using:
    renderLabel() ?>
    renderError() ?>

    You could also simply use:
    renderRow() ?>
    (yes, this produces a structure, except when in a )

    I have two questions myself:
    1) When hitting the ‘add’ button I get a 404 ajax response except when changing the url in the ajax request to ‘/frontend_dev.php/event/add?num=’+num . Even when I’ve added the /add to the routing. Anyone else having this problem and knows a solution?
    2) Removing a new field works great. But I’m still not sure how to do this with existing fields. Do you have a suggestion for this?

    Thanks!

    kaore August 3rd, 2010 @ 20:25

    1) I usually get that when I forget to empty the cache in prod mode (you don’t get it in dev – frontend_dev.php mode)

    2) Depends if you want the data to be removed at the moment you hit ‘delete’ or when you submit the full form… In the first case, you could make an ajax call to an action which would deal with deleting the record based on the id sent by the call. In the second case, you could do it after reconstructing the form fields in the bind method, passing an additional parameter for each field having been selected for deletion.

    Jasper August 4th, 2010 @ 15:48

    Thanks that helps!

    I found a bit on removing fields in:
    http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine

    Both this tutorial as well as the ‘The More w/ Symfony > Advanced Forms’ (http://www.symfony-project.org/more-with-symfony/1_4/en/06-Advanced-Forms) handle the updating in the ‘saveEmbeddedForms’ function instead of the ‘bind’. Is there a specific reason you are using the ‘bind’ and not the ‘saveEmbeddedForms’?

    kaore August 4th, 2010 @ 20:01

    Yes I answered a bit quickly. You shouldn’t write anything in the db until you know the data it is valid, so coming back to the second case of point 2) in my previous comment, it should definitely be handled in a save method.

    Karol September 22nd, 2010 @ 14:15

    Thanks man! this is what I was looking for. Great tutorial :)

    Bernhard October 9th, 2010 @ 00:42

    Hi,

    how can you change inside the JS between then frontend_dev.php and the production environment for testing?

    And during testing the new form (add through AJAX appears three times (in header, dev_toolBar and the form itself…

    Thx

    Bernhard October 9th, 2010 @ 12:22

    Hi,

    was a bit lazy in reading… I had also varous “”-tags so giving it and “id” and changing the js-code to select this specific ul helped.

    But I still can’t save my added form…

    Bernhard

    Tommy October 28th, 2010 @ 07:30

    Hi,

    Thanks for your Doctrine tutorial. I used Propel in symfony before. You make me started a new doctrine symfony project, really thanks!

    tejal December 1st, 2010 @ 10:31

    Hi!

    When i do edit in my form that time when validation error come and value of my control comes from db but after validation error they are gone from control.
    and also the new fields are not displayed…

    Sorry for my bad english.

    Please help me as soon as possible by the way any other functionality you create that’s really good and very useful to me.

    Best regards,
    Tejal

    codecowboy December 20th, 2010 @ 22:06

    Hi,

    Thanks for taking the time to post this tutorial. I have a couple of questions:

    Is it really necessary to do a round trip to the server to add the new occurrence fields? Wouldn’t it be more efficient to add these in the browser only via JS if all you need to do is keep a count of the the number of fields?

    Why do this in the JS – $(‘.removenew’).unbind(‘click’); – when the button has been removed from the screen. Is this best practice or something?

    thanks again

    shahin zabeti December 22nd, 2010 @ 04:43

    Just one thing, best of ever.
    thanks.

    Chuck Haines January 7th, 2011 @ 06:06

    I followed your tutorial and it’s great except I’m using a tinyMCE as the widget for two fields on my embedded form. If I use your render it doesn’t render the tiny MCE fields but rather a generic widget. How would I get it to render my tinyMCE fields (as I’ve got them defined in the configure of my embedded form).

    Titogelo February 23rd, 2011 @ 22:17

    Hi, first of all really nice jobs men.

    I used your code to did that i wanted to do, all things are ok, i mean i didn’t have error or something like that, but if i wanted to save something just didn’t save it. If you want and if you have time i’m very pleasure to show you my code by mail and maybe you get an idea that what it’s happen

    sorry for my english i’m spanish.

    Finally, just say that i found this article really interesting and usefull, thanks.

    bye

    oa2004 March 5th, 2011 @ 00:56

    How would you extend this to embed multiple 1-to-n relations in one form (e.g. User with multiple emails, phone numbers and postal adresses)?

    I changed the addNewFields method to take the $num parameter and an additional $name parameter and then generate the form and object via ReflectionClass.
    But if I add fields for one relation the bound fields of another relation are lost and when I submit the form I get an ‘Unexpected form field’ error.

    tomfrog April 21st, 2011 @ 21:58

    Nice tuto, thanks !!

    For people having problems with the ‘add?num=’+num URL in the JS code, wanting to have frontend_dev.php/ and no 404 error, etc… you could display the code in your template/partial and change the bit of code with:

    function addNewField(num){
    return $.ajax({
    type: ‘GET’,
    url: ‘?num=’+num,
    async: false
    }).responseText;
    }

    Et voilĂ  ! :)

    tomfrog April 21st, 2011 @ 22:00

    ummm obviously my code above isn’t displayed correctly so the “url:” line again with spaces added

    url: ‘?num=’+num

    Just remove the spaces in

    tomfrog April 21st, 2011 @ 22:01

    Ok that sucks… sorry for my 2 previous comments… just use the url_for helper

    hendra1 April 28th, 2011 @ 12:33

    wow this awsome symfony 1.4 form embedd,
    very clean explatnation, easy to implement

    thanks for sharing this tutorial. It really help my work.

    dev01 May 22nd, 2011 @ 03:49

    thank you very much for this tutorial

    Cunt@quinte September 24th, 2011 @ 00:35

    Hi kaore,

    This is a Excellent tuto congrats.

    I have a trouble when the form is saving, in the related table save other data but not the id of the relation.
    I mean, in your sample, in occurrence save other fields but not the event_id.
    do you have any idea about it?

    Bye

    Pd/ excuse my English.

    samoreon November 2nd, 2011 @ 20:10

    Great tuto…!!! Tnx a lot, the best I’ve read and I read a lot of them, I implement a succes delete complement for any embedded form, and works great with sf 1.4 and Doctrine…

    Bharat December 8th, 2011 @ 17:23

    Man terrible mistake at

    it should be …

    Sonia June 1st, 2012 @ 21:31

    Thanks a lot for this article. You have saved me from lots of headaches, we have been stuck for the whole month with this problem.
    It’s a very complete and advanced work, thank you again for sharing.

    Sonia June 15th, 2012 @ 21:19

    Thanks to your tuto I could build all the embeded form, but also wanted the option of deleting fields already saved in the database (not just the new ones), so I mixed this information with the one in http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine
    The problem I found is that when one field is deleted, a new empty field is included giving the following mistake “SQLSTATE[23000]: Integrity constraint violation: 1452 Cannot add or update a child row: a foreign key constraint fails”
    I have debug and I know this is because and empty row is added, but althought I have looked and read a lot about embeded form I can not find the reason and solution.
    Do you know what is happening and how can I fix it?
    Thank you once more, and sorry for my English.

    Chandima October 12th, 2012 @ 18:21

    It’s a great tutorial. It saved my time.

    BTW, I have the same problem Sonia has. It tries to insert an empty record somewhere and hard to identify when try to implement an occurrence delete as mentioned in http://prendreuncafe.com/blog/post/2009/11/29/Embedding-Relations-in-Forms-with-Symfony-1.3-and-Doctrine

    It’s highly appreciated if somebody could post a solution if you have overcome this, plus any other feasible solution.

    Sonia >> Have you found the answer??

    Chandima October 13th, 2012 @ 10:40

    The above problem solved by adding saveEmbeddedForms() part mentioned in the other tutorial. I don’t know how it works exactly, but it works. Cheers, now it’s a total solution.

    ALM December 25th, 2012 @ 14:43

    it is really very important and easy to understand tutorial for me. so thanx a lot.
    If you have also something regarding ajax and symfony 1.4 using jquery library please post it. i have a lot of trouble with it. Am just unable to use ajax in symfony 1.4

    Leave a Reply


    RSS 2.0You can follow any responses to this entry through You can leave a response, ou trackback from your own site.