Next → Seventh Step, delete tasks Fifth Step, getting dynamic ← Prev

Sixth Step, open and close tasks

Since the nature of tasks is to be done eventually we will need some way to mark it as done or open tasks again.

Jump into view/index.xhtml and do the following:

<?r @tasks.each do |title, status, toggle| ?>
  <li>
    #{title}: #{status} - [ #{toggle} ]
  </li>
<?r end ?>

We added a new element here, toggle, the Controller should give us a link to change the status corresponding to the status of the task, so off we go and change the index method on the controller once again:

def index
  @tasks = []
  TodoList.original.each do |title, value|
    if value[:done]
      status = 'done'
      toggle = A('Open Task', :href => Rs(:open, title))
    else
      status = 'not done'
      toggle = A('Close Task', :href => Rs(:close, title))
    end
    @tasks << [title, status, toggle]
  end
  @tasks.sort!
end

Wow, quite some new stuff here. Let me explain that in detail.

We first decide whether a task is done or not, then go on and provide a link to toggle the status, A and Rs are both methods that help you do that. The result will be something like:

<a href="/open/Wash+dishes">Close Task</a>

Rs actually is responsible to build the links href, for more information please take a look at the RDoc for LinkHelper.

Also, you might have noticed that the tasks were changing order on every reload, which is because we were using a Hash, which are per definition unsorted, so now we use an array to hold our tasks and sort it.

As usual since the links for open and close don't lead anywhere, add the corresponding methods to the Controller:

def open title
  task_status title, false
  redirect Rs()
end
 
def close title
  task_status title, true
  redirect Rs()
end
 
private
 
def task_status title, status
  task = TodoList[title]
  task[:done] = status
  TodoList[title] = task
end

Oh, now what have we got here? private declares that methods from here on are only to be used within the Controller itself, we define an #task_status method that takes the title and status to be set so we don't have to repeat that code in #open and #close and follow the DRY (Don't repeat yourself) paradigm.

Another thing we have not encountered so far is that you can define your public methods to take parameters on their own, they will be calculated from requests.

'/open/Wash+dishes'

will translate into:

open('Wash dishes')

Which in turn will call

task_status('Wash dishes', false)

That's it, go on and try it :)

Next → Seventh Step, delete tasks Fifth Step, getting dynamic ← Prev

 
Back to top
tutorials/todolist-6.txt · Last modified: 2008/01/31 03:37 by reacher