Skip to content

Commit

Permalink
in place editing
Browse files Browse the repository at this point in the history
  • Loading branch information
clemens committed Nov 4, 2009
1 parent 4d6f710 commit 4c55be1
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 8 deletions.
14 changes: 13 additions & 1 deletion app/controllers/lists_controller.rb
@@ -1,4 +1,6 @@
class ListsController < ApplicationController
before_filter :set_list, :only => [:update, :destroy]

def create
@list = List.new(params[:list])

Expand All @@ -9,6 +11,11 @@ def create
end
end

def update
@list.update_attributes(params[:list])
render :json => @list, :status => 200
end

def reorder
lists = List.find(params[:list])
params[:list].each_with_index do |list_id, index|
Expand All @@ -18,8 +25,13 @@ def reorder
end

def destroy
@list = List.find(params[:id])
@list.destroy
render :text => 'ok', :status => 200
end

protected

def set_list
@list = List.find(params[:id])
end
end
4 changes: 2 additions & 2 deletions app/views/tasks/index.html.erb
Expand Up @@ -3,7 +3,7 @@
<% content_tag_for(:li, list) do %>
<h2>
<span class="action drag">Drag</span>
<%=h list.name %>
<span class="name"><%=h list.name %></span>
<span class="delete_link"><%= link_to 'Delete', list_path(list), :id => "delete_list_#{list.id}", :class => 'action delete' %></span>
</h2>
<ul id="list_<%= list.id %>_tasks" class="tasks">
Expand All @@ -12,7 +12,7 @@
<% form_for(task) do |f| %>
<span class="action drag">Drag</span>
<%= f.check_box :done, :id => "#{dom_id(task)}_done" %>
<%= f.label "#{task.id}_done", h(task.name) %>
<span class="name"><%= h(task.name) %></span>
<span class="delete_link"><%= link_to 'Delete', task_path(task), :id => "delete_task_#{task.id}", :class => 'action delete' %></span>
<% end -%>
<% end %>
Expand Down
20 changes: 18 additions & 2 deletions features/managing_tasks.feature
Expand Up @@ -18,6 +18,14 @@ Feature: Managing tasks
And I click somewhere else on the page
Then there should be a task named "Wash dishes" in the list "Household"

Scenario: Renaming an task
Given I am on the task list page
When I click on "Do laundry"
And I fill in "Do the laundry" as the task's name
And I click somewhere else on the page
Then there should be a task named "Do the laundry"
Then there should not be a task named "Do laundry"

Scenario: Reordering tasks
Given I am on the task list page
When I drag the task "Do laundry" above "Buy milk"
Expand All @@ -36,6 +44,14 @@ Feature: Managing tasks
And I click somewhere else on the page
Then there should be a list named "Work"

Scenario: Renaming a list
Given I am on the task list page
When I click on "Household"
And I fill in "House" as the list's name
And I click somewhere else on the page
Then there should be a list named "House"
Then there should not be a list named "Household"

Scenario: Reordering lists
Given I am on the task list page
When I drag the list "Household" above "Garden"
Expand All @@ -56,11 +72,11 @@ Feature: Managing tasks

Scenario: Marking a task as done
Given I am on the task list page
When I click on "Mow the lawn"
When I check the task "Mow the lawn"
Then the task "Mow the lawn" should be marked as done

Scenario: Marking a task as open
Given the task "Mow the lawn" is marked as done
And I am on the task list page
When I click on "Mow the lawn"
When I uncheck the task "Mow the lawn"
Then the task "Mow the lawn" should be marked as open
31 changes: 29 additions & 2 deletions features/step_definitions/task_steps.rb
Expand Up @@ -39,11 +39,23 @@ def blur(element, options = {})
blur(locate_field('new_task_name')) # should actually go to When /^I click somewhere else on the page$/
end

When /^I fill in "([^\"]*)" as the task's name$/ do |name|
task_field = locate_field('task[name]')
fill_in(task_field, :with => name)
blur(task_field)
end

When /^I fill in "([^\"]*)" as the new list's name$/ do |name|
fill_in('new_list_name', :with => name)
blur(locate_field('new_list_name')) # should actually go to When /^I click somewhere else on the page$/
end

When /^I fill in "([^\"]*)" as the list's name$/ do |name|
list_field = locate_field('list[name]')
fill_in(list_field, :with => name)
blur(list_field)
end

When /^I click somewhere else on the page$/ do
# huh?
end
Expand All @@ -67,9 +79,13 @@ def blur(element, options = {})
end

When /^I drag the list "([^\"]*)" above "([^\"]*)"$/ do |list_1_name, list_2_name|
drag_handle = locate_element(list_1_name) { locate_element(:class => 'drag') }
list_1 = List.find_by_name(list_1_name)
list_2 = List.find_by_name(list_2_name)
drag_handle = locate_element("list_#{list_1.id}") { locate_element(:class => 'drag') }
# a little weird: since we limit to sorting on the y-axis, we have to drag one handle "on" the other
target = locate_element("list_#{list_2.id}") { locate_element(:class => 'drag') }

drag(drag_handle, :to => list_2_name)
drag(drag_handle, :to => target)
end

When /^I hover the task "([^\"]*)"$/ do |task|
Expand All @@ -96,6 +112,12 @@ def blur(element, options = {})
click_link('add_list')
end

When /^I (check|uncheck) the task "([^\"]*)"$/ do |action, task|
task = Task.find_by_name(task)
task_checkbox = locate_element("task_#{task.id}") { locate_element("task_#{task.id}_done") }
send(action, task_checkbox)
end

Then /^there should be a task named "([^\"]*)" in the list "([^\"]*)"$/ do |task, list|
list = List.find_by_name(list)
task = Task.find_by_name(task)
Expand All @@ -116,6 +138,11 @@ def blur(element, options = {})
(List.find_by_name(list_1_name).position < List.find_by_name(list_2_name).position).should be_true
end

Then /^there should be a task named "([^\"]*)"$/ do |task|
locate_element(task).should_not be_nil
Task.find_by_name(task).should_not be_nil
end

Then /^there should not be a task named "([^\"]*)"$/ do |task|
locate_element(task).should be_nil
Task.find_by_name(task).should be_nil
Expand Down
62 changes: 61 additions & 1 deletion public/javascripts/application.js
Expand Up @@ -22,6 +22,28 @@ $(document).ready(function() {
}
};

var existingTaskOnBlur = function() {
var task_name_field = $(this);
var task = task_name_field.closest('.task');
var task_id = task.attr('id').match(/task_(\d+)/)[1];
var task_name = task_name_field.val();

if(task_name != '') {
$.ajax({
url: '/tasks/' + task_id,
type: 'post',
dataType: 'json',
data: '_method=put&task[name]=' + task_name,
success: function(data, textStatus) {
task_name_field.replaceWith(task_name);
task.effect('highlight');
}
});
} else {
task_name_field.replaceWith(task_name);
}
};

var newListOnBlur = function() {
var list_name = $('#new_list_name').val();

Expand All @@ -42,6 +64,28 @@ $(document).ready(function() {
}
};

var existingListOnBlur = function() {
var list_name_field = $(this);
var list = list_name_field.closest('.list');
var list_id = list.attr('id').match(/list_(\d+)/)[1];
var list_name = list_name_field.val();

if(list_name != '') {
$.ajax({
url: '/lists/' + list_id,
type: 'post',
dataType: 'json',
data: '_method=put&list[name]=' + list_name,
success: function(data, textStatus) {
list_name_field.replaceWith(list_name);
list.effect('highlight');
}
});
} else {
list_name_field.replaceWith(list_name);
}
};

var onListUpdate = function(event, ui) {
$.ajax({
url: '/lists/reorder',
Expand Down Expand Up @@ -156,7 +200,7 @@ $(document).ready(function() {
$('.task, .list h2').mouseover(onElementHover);
$('.task, .list h2').mouseout(onElementBlur);

$('.task input[type=checkbox]').live('click', function() {
$('.task input[type=checkbox]').change(function() {
var checkbox = $(this);
var task = checkbox.closest('.task');

Expand All @@ -174,6 +218,22 @@ $(document).ready(function() {
});
});

$('.task .name').live('click', function(event) {
event.preventDefault();

var input = $('<input type="text" name="task[name]" value="' + $(this).html() + '" />');
$(this).html(input);
input.blur(existingTaskOnBlur).focus();
});

$('.list h2 .name').live('click', function(event) {
event.preventDefault();

var input = $('<input type="text" name="list[name]" value="' + $(this).html() + '" />');
$(this).html(input);
input.blur(existingListOnBlur).focus();
});

// sorting
$('.list .tasks').sortable({
handle: '.drag',
Expand Down

0 comments on commit 4c55be1

Please sign in to comment.