Todo list with Symfony 1.4 – Part 8 (Editing a list)
First of all, what happens here is that the user wants to edit the list and its tasks, all in the same page. Here we have our first issue since we have a form for a task and form for a list but we need to merge them into one.
Let’s take a look at the code then:
Editing the list
The editList action retrieves the list at stake and creates a new form.
At the template, we display the list’s name together with a couple of links by its side, one for cancel the edition and the other for deleting the whole list. Once this last is clicked, the deleteList action (which is not shown here, since it is not that relevant), is executed. This action deletes the list and redirects the user to the home page.
It is important to notice that in this list we display “all” the tasks, even those that have been marked as “done”. This is why, I crossedout done tasks.
Now, as we said in the beginning of this post, the user should be able to edit the list name and the description of every task at the same page.
Browsing the Symfony project documentation, we find a book called: The more with symfony. In this book there’s a section called: Advanced forms, where you can read everything you need to create forms like the one we need here. That is, to create a form which embeds other subforms inside.
Since this kind of situations were not that common, the first releases of Symfony did not pay too much attention to it and in fact the initial procedure to make it, was too complicated. Fortunately, after release 1.3 and with Doctrine, form embedding turned out to be way much easier.
Let’s see, we need to have a list form with its name widget and below a list of editable tasks, that is task forms with an editable description field. In order to do this, we need to create a new MylistForm called: MylistFormWithTasks().
If you look at the source code of that form class, you’ll see that if you made a good schema file, and created a Tasks relation (in this case), all you have to do is add the following line:
Easy uh? In addition to this, I added an extra hidden field to keep track of deleted tasks, as you will see later. Then, if you look at the template again, you’ll see that we go through the form['Tasks'] array with a classic foreach and display the description task widget.
Removing individual tasks
Now, since we also need to be able to remove tasks by clicking an icon next to each task. We must have a way to identify each task. That ‘s is why when we display every task input, we store the task id as the id attribute of the task link. We can retrieve that info directly from the form object doing this: task['id']->getValue().
Once the form is submitted, the updateList action is exectuted and the list is updated.
So far so good, but what happens when we would like to remove a single task. Here’s where JQuery comes to action. When the user clicks delete in the cross icon next to the task, we slowly fade the task away by the time we add the task id to the deletedTasks hidden field we previously added in the form class.
This way, tasks are not longer then when deleted but the actual removal occurs in the action code as you can see. If you analyze the processForm() method, you’ll see that after checking that the variable exists, we store it into another one and remove it from the request (to avoid issues when validating the form).
Then, if the form is valid, we go ahead and process this hidden field. We convert the string into an array and traverse the array, retrieving every single Task object and deleting it.
If you took the time to read every part of this project, before you jump into any conclusion, I would like to emphasize a few concepts:
- This application is an easier version of the 37signals tadalist. It was not my intention whatsoever to copy the original one or say this is my Todo list idea. I really respect others work and their version is superb.
- The main objective of this post is to be educational although I am aware of the fact that refactoring could be done in many sections.
- This is also supposed to help those who have not gotten the expertise in working with Symfony but find it a great framework.
Having said all of the above, I hope you enjoy the app as much as I did while I was writing this set of posts and remember, programming is about having fun :)