migrate update for context, project, tickler and calendar

This commit is contained in:
Reinier Balt 2010-12-25 16:28:53 +01:00
parent 33f68df154
commit c64e1bcd80
16 changed files with 494 additions and 402 deletions

View file

@ -8,6 +8,7 @@
update_active_projects_container();
add_project();
clear_form();
TracksPages.page_notify('notice', "Created new project '<%= @project.name%>'", 5);
<% end -%>
<% else -%>
TracksPages.show_errors(html_for_error_messages());

View file

@ -1,42 +1,40 @@
<% if @saved -%>
TracksPages.page_notify('notice', '<%=t('projects.project_saved_status')%>', 5);
<% if source_view_is :project_list -%>
<% if @state_changed -%>
remove_and_re_add_project();
<% else -%>
replace_project_form_with_updated_project();
<% end -%>
ProjectListPage.update_all_states_count(<%=@active_projects_count%>, <%=@hidden_projects_count%>, <%=@completed_projects_count%>);
ProjectListPage.show_or_hide_all_state_containers(<%= @show_active_projects %>, <%= @show_hidden_projects %>, <%= @show_completed_projects %>);
update_project_list_page();
<% else # assume source_view :project
-%>
remove_project_edit_form();
update_and_show_project_settings();
TracksForm.set_project_name("<%= escape_javascript(@project.name)%>");
<% if @project.default_context %>
TracksForm.set_context_name_and_default_context_name("<%= escape_javascript(@project.default_context.name)%>");
<% end %>
<% if @project.default_tags %>
TracksForm.set_tag_list("<%= escape_javascript(@project.default_tags)%>");
<% end %>
TracksPages.update_sidebar(html_for_sidebar());
update_project_page();
<% end %>
TracksForm.set_project_name_and_default_project_name("<%= escape_javascript(@project.name)%>");
<% else -%>
TracksPages.show_edit_errors(html_for_error_messages());
<% end %>
function update_project_list_page() {
<% if @state_changed -%>
remove_and_re_add_project();
<% else -%>
replace_project_form_with_updated_project();
<% end -%>
ProjectListPage.update_all_states_count(<%=@active_projects_count%>, <%=@hidden_projects_count%>, <%=@completed_projects_count%>);
ProjectListPage.show_or_hide_all_state_containers(<%= @show_active_projects %>, <%= @show_hidden_projects %>, <%= @show_completed_projects %>);
}
function update_project_page() {
remove_project_edit_form();
update_and_show_project_settings();
TracksForm.set_project_name("<%= escape_javascript(@project.name)%>");
<% if @project.default_context %>
TracksForm.set_context_name_and_default_context_name("<%= escape_javascript(@project.default_context.name)%>");
<% end %>
<% if @project.default_tags %>
TracksForm.set_tag_list("<%= escape_javascript(@project.default_tags)%>");
<% end %>
TracksPages.update_sidebar(html_for_sidebar());
}
function remove_project_edit_form() {
$('#<%=dom_id(@project, 'edit')%>').hide(500, function() {$('#<%=dom_id(@project, 'edit')%>').remove();} );
}

View file

@ -1,60 +1,61 @@
<div id="error_status"><%= error_messages_for("todo", :object_name => 'action') %></div>
<%
todo = edit_form
form_for(todo, :html=> { :name=>'todo', :id => dom_id(@todo, 'form'), :class => 'inline-form edit_todo_form' }) do |t|%>
<div id="error_status"><%= error_messages_for("todo", :object_name => 'action') %></div>
<%= hidden_field( "todo", "id" ) -%>
<%= source_view_tag( @source_view ) -%>
<%= "<INPUT TYPE=\"hidden\" name=\"_tag_name\" value=\""+ @tag_name+"\">" unless @tag_name.nil? -%>
<%= t.hidden_field( "id" ) -%>
<%= source_view_tag( @source_view ) -%>
<%= content_tag(:input, "", :type=>"hidden", :name=>"_tag_name", :value=>"#{@tag_name}") if @tag_name -%>
<label for="<%= dom_id(@todo, 'description') %>"><%= t('common.description') %></label>
<%= text_field( "todo", "description", "size" => 30, "tabindex" => 8, "maxlength" => 100) %>
<label for="<%= dom_id(@todo, 'description') %>"><%= t('common.description') %></label>
<%= t.text_field( "description", "size" => 30, "tabindex" => 8, "maxlength" => 100) %>
<label for="<%= dom_id(@todo, 'notes') %>"><%= t('common.notes') %></label>
<%= text_area( "todo", "notes", "cols" => 29, "rows" => 4, "tabindex" => 9) %>
<label for="<%= dom_id(@todo, 'notes') %>"><%= t('common.notes') %></label>
<%= t.text_area( "notes", "cols" => 29, "rows" => 4, "tabindex" => 9) %>
<div class="project_input">
<label for="<%= dom_id(@todo, 'project_name') %>"><%= t('common.project') %></label>
<input id="<%= dom_id(@todo, 'project_name') %>" name="project_name" autocomplete="off" tabindex="10" size="30" type="text" value="<%= @todo.project.nil? ? 'None' : @todo.project.name.gsub(/"/,"&quot;") %>" />
</div>
<div class="project_input">
<label for="<%= dom_id(@todo, 'project_name') %>"><%= t('common.project') %></label>
<input id="<%= dom_id(@todo, 'project_name') %>" name="project_name" autocomplete="off" tabindex="10" size="30" type="text" value="<%= @todo.project.nil? ? 'None' : @todo.project.name.gsub(/"/,"&quot;") %>" />
</div>
<div class="context_input">
<label for="<%= dom_id(@todo, 'context_name') %>"><%= t('common.context') %></label>
<input id="<%= dom_id(@todo, 'context_name') %>" name="context_name" autocomplete="off" tabindex="11" size="30" type="text" value="<%= @todo.context.name %>" />
</div>
<div class="context_input">
<label for="<%= dom_id(@todo, 'context_name') %>"><%= t('common.context') %></label>
<input id="<%= dom_id(@todo, 'context_name') %>" name="context_name" autocomplete="off" tabindex="11" size="30" type="text" value="<%= @todo.context.name %>" />
</div>
<label class="tag_list_label" for="<%= dom_id(@todo, 'tag_list') %>"><%= t('todos.tags') %></label>
<%= text_field_tag 'tag_list', tag_list_text, :id => dom_id(@todo, 'tag_list'), :size => 30, :tabindex => 12 %>
<label class="tag_list_label" for="<%= dom_id(@todo, 'tag_list') %>"><%= t('todos.tags') %></label>
<%= text_field_tag 'tag_list', tag_list_text, :id => dom_id(@todo, 'tag_list'), :size => 30, :tabindex => 12 %>
<div class="due_input">
<label for="<%= dom_id(@todo, 'due_label') %>">Due</label>
<%= date_field_tag("todo[due]", dom_id(@todo, 'due'), format_date(@todo.due), "tabindex" => 13) %>
<a href="#" id="<%= dom_id(@todo, 'due_x') %>" class="date_clear" title="<%= t('todos.clear_due_date') %>">
<%= image_tag("delete_off.png", :alt => t('todos.clear_due_date') ) %>
</a>
</div>
<div class="show_from_input">
<label for="<%= dom_id(@todo, 'show_from') %>"><%= t('todos.show_from') %></label>
<%= date_field_tag("todo[show_from]", dom_id(@todo, 'show_from'), format_date(@todo.show_from), "tabindex" => 14) %>
<a href="#" id="<%= dom_id(@todo, 'show_from_x') %>" class="date_clear" title="<%= t('todos.clear_show_from_date') %>">
<%= image_tag("delete_off.png", :alt => t('todos.clear_show_from_date') ) %>
</a>
</div>
<label class="predecessor_list_label" for="<%= dom_id(@todo, 'predecessor_list') %>"><%= t('todos.depends_on_separate_with_commas') %></label>
<%= text_field_tag 'predecessor_list', predecessor_list_text, :id => dom_id(@todo, 'predecessor_list'), :size => 30, :tabindex => 15 %>
<% if controller.controller_name == "project" || @todo.deferred? -%>
<input type="hidden" name="on_project_page" value="true" />
<% end -%>
<div class="submit_box">
<div class="widgets">
<button type="submit" class="positive" id="<%= dom_id(@todo, 'submit') %>" tabindex="16">
<%= image_tag("accept.png", :alt => "") %>
<%= t('common.update') %>
</button>
<a href="#" class="negative">
<%= image_tag("cancel.png", :alt => "") %>
<%= t('common.cancel') %>
<div class="due_input">
<label for="<%= dom_id(@todo, 'due_label') %>">Due</label>
<%= date_field_tag("todo[due]", dom_id(@todo, 'due'), format_date(@todo.due), "tabindex" => 13) %>
<a href="#" id="<%= dom_id(@todo, 'due_x') %>" class="date_clear" title="<%= t('todos.clear_due_date') %>">
<%= image_tag("delete_off.png", :alt => "Clear due date") %>
</a>
</div>
</div>
<div class="show_from_input">
<label for="<%= dom_id(@todo, 'show_from') %>"><%= t('todos.show_from') %></label>
<%= date_field_tag("todo[show_from]", dom_id(@todo, 'show_from'), format_date(@todo.show_from), "tabindex" => 14) %>
<a href="#" id="<%= dom_id(@todo, 'show_from_x') %>" class="date_clear" title="<%= t('todos.clear_show_from_date') %>">
<%= image_tag("delete_off.png", :alt => "Clear show from date") %>
</a>
</div>
<label class="predecessor_list_label" for="<%= dom_id(@todo, 'predecessor_list') %>"><%= t('todos.depends_on_separate_with_commas') %></label>
<%= text_field_tag 'predecessor_list', predecessor_list_text, :id => dom_id(@todo, 'predecessor_list'), :size => 30, :tabindex => 15 %>
<div class="submit_box">
<div class="widgets">
<button type="submit" class="positive" id="<%= dom_id(@todo, 'submit') %>" tabindex="16">
<%=image_tag("accept.png", :alt => "") %>
Update
</button>
<a href="#" class="negative">
<%=image_tag("cancel.png", :alt => "") %>
Cancel
</a>
</div>
</div>
<% end %>

View file

@ -37,9 +37,7 @@ parameters += "&_tag_name=#{@tag_name}" if @source_view == 'tag'
</div>
</div>
<div id="<%= dom_id(todo, 'edit') %>" class="edit-form" style="display:none">
<% form_remote_tag_edit_todo do -%>
<% #note: edit form will load here remotely -%>
<div class="placeholder"> </div>
<% end -%>
<% #note: edit form will load here remotely -%>
<div class="placeholder"> </div>
</div>
</div>

View file

@ -1,4 +1,3 @@
unless @due_tickles.empty?
#TODO: why not just add the new items here in addition to notifying?
page.notify :notice, t('todos.tickler_items_due', :count => @due_tickles.length), 5.0
end
<% unless @due_tickles.empty? -%>
TracksPages.page_notify('notice', "<%=t('todos.tickler_items_due', :count => @due_tickles.length)%>", 5);
<% end -%>

View file

@ -40,6 +40,7 @@ function insert_new_context_with_new_todo() {
function add_todo_to_existing_context() {
<% if source_view_is_one_of(:todo, :deferred, :tag) -%>
TodoItemsContainer.ensureVisibleWithEffectAppear("c<%=@todo.context_id%>");
$('#<%=empty_container_msg_div_id%>').hide();
<% end -%>
$('#<%=item_container_id(@todo)%>').append(html_for_new_todo());
$('#<%= dom_id(@todo)%>').effect('highlight', {}, 2000 );

View file

@ -1,5 +1,17 @@
page[dom_id(@todo, 'form')].find('.placeholder').show().replace_html :partial => 'todos/edit_form'
page[dom_id(@todo, 'edit')].show
page[dom_id(@todo, 'line')].hide
page[dom_id(@todo, 'form')].find('input#todo_description').show().focus
page << "enable_rich_interaction();"
hide_todo();
replace_placeholder_with_form();
enable_rich_interaction();
function hide_todo() {
$('#<%= dom_id(@todo, 'line') %>').hide();
}
function replace_placeholder_with_form() {
$('#<%=dom_id(@todo, 'edit')%>').html(html_for_edit_form());
$('#<%=dom_id(@todo, 'edit')%>').show();
$('#<%=dom_id(@todo, 'form')%> input#todo_description').focus();
}
function html_for_edit_form() {
return "<%= escape_javascript(render(:partial => 'todos/edit_form', :object => @todo)) %>"
}

View file

@ -1,164 +1,136 @@
if @saved
# show update message
status_message = @todo.deferred? ? t('todos.action_saved_to_tickler') : t('todos.action_saved')
status_message = t('todos.added_new_project') + ' / ' + status_message if @new_project_created
status_message = t('todos.added_new_context') + ' / ' + status_message if @new_context_created
status_message = @message || status_message
page.notify :notice, status_message, 5.0
if source_view_is_one_of(:todo, :context, :tag)
if @context_changed || @todo.deferred? || @todo.pending?
page[@todo].remove
if (@remaining_in_context == 0)
# remove context container from page if empty
if @context_changed
source_view do |from|
from.todo { page.visual_effect :fade, "c#{@original_item_context_id}", :duration => 0.4 }
from.tag { page.visual_effect :fade, "c#{@original_item_context_id}", :duration => 0.4 }
from.context { page.show "c#{@original_item_context_id}empty-nd" }
end
else
source_view do |from|
from.todo { page.visual_effect :fade, "c#{@todo.context.id}", :duration => 0.4 }
from.tag { page.visual_effect :fade, "c#{@todo.context.id}", :duration => 0.4 }
from.context { page.show "c#{@original_item_context_id}empty-nd" }
end
end
end
<% if !@saved -%>
TracksPages.show_edit_errors(html_for_error_messages());
<% else
if source_view_is_one_of(:todo, :tag) && @todo.active?
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@todo.context_id}"
page.call "todoItems.expandNextActionListingByContext", "c#{@todo.context_id}items", true
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
# show all todos in context
page.insert_html :bottom, "c#{@todo.context_id}items", :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
end
# jquery animations are async, so first collect all animation steps,
# then execute them sequential. All steps are functions which are passed a function
# with the next animation steps
if source_view_is(:tag) && @todo.deferred?
# show todo in deferred container
page.insert_html :bottom, "tickleritems", :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
end
# update badge count
page.replace_html("badge_count", @remaining_in_context) if source_view_is :context
page.replace_html("badge_count", @down_count) if source_view_is :todo
# show todo in context
page.delay(0.3) do
page.call "todoItems.ensureContainerHeight", "c#{@original_item_context_id}items"
if source_view_is_one_of(:todo, :tag) && @todo.active?
page.call "todoItems.ensureContainerHeight", "c#{@todo.context_id}items"
page.visual_effect :highlight, dom_id(@todo), :duration => 3
end
if @context_changed
source_view do |from|
from.todo {page << "$('#c#{@todo.context_id} h2').effect('highlight', {}, 3000)" }
from.tag {page << "$('#c#{@todo.context_id} h2').effect('highlight')" }
end
end
end
else
if @original_item_was_deferred && source_view_is(:tag)
# we go from the deferred container to a context container in tag view
page[@todo].remove
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@todo.context_id}"
page.call "todoItems.expandNextActionListingByContext", "c#{@todo.context_id}items", true
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
# show all todos in context
page.insert_html :bottom, "c#{@todo.context_id}items", :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
page['tickler-empty-nd'].show if @deferred_tag_count == 0
else
page.replace dom_id(@todo), :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
end
page.visual_effect :highlight, dom_id(@todo), :duration => 3
end
elsif source_view_is :project
if @project_changed
page[@todo].remove
page.show("p#{@original_item_project_id}empty-nd") if (@remaining_undone_in_project == 0)
page.replace_html "badge_count", @remaining_undone_in_project
elsif @todo.deferred?
page[@todo].remove
page.show("p#{@original_item_project_id}empty-nd") if (@remaining_undone_in_project == 0)
page.insert_html :bottom, "tickler", :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
page['tickler-empty-nd'].hide
page.replace_html "badge_count", @down_count
elsif @todo_was_activated_from_deferred_state
page[@todo].remove
page['tickler-empty-nd'].show if (@deferred_count == 0)
page.insert_html :bottom, "p#{@todo.project_id}items", :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@todo), :duration => 3
page["p#{@todo.project_id}empty-nd"].hide
page.replace_html "badge_count", @down_count
else
page.replace_html "p#{@todo.project_id}items", :partial => 'todos/todo', :collection => @todo.project.not_done_todos,
:locals => { :parent_container_type => parent_container_type }
page.replace "tickler", :partial => 'todos/deferred', :locals => {
:deferred => @todo.project.deferred_todos,
:collapsible => false,
:append_descriptor => "in this project",
:parent_container_type => 'project',
:pending => @todo.project.pending_todos }
page['tickler-empty-nd'].show if (@deferred_count == 0 and @pending_count == 0)
page.visual_effect :highlight, dom_id(@todo), :duration => 3
end
elsif source_view_is :deferred
if !@todo.deferred?
page[@todo].remove
page.show(empty_container_msg_div_id) if (@down_count == 0)
page.replace_html "badge_count", @down_count
elsif @context_changed
page[@todo].remove
page.visual_effect(:fade, "c#{@original_item_context_id}", :duration => 0.4) if (@remaining_in_context == 0)
page.call "todoItems.ensureVisibleWithEffectAppear", "c#{@todo.context_id}"
page.call "todoItems.expandNextActionListingByContext", "c#{@todo.context_id}items", true
page[empty_container_msg_div_id].hide unless empty_container_msg_div_id.nil?
page.insert_html :bottom, "c#{@todo.context_id}items", :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
page.replace_html("badge_count", @down_count)
page.delay(0.5) do
page.call "todoItems.ensureContainerHeight", "c#{@original_item_context_id}items"
page.call "todoItems.ensureContainerHeight", "c#{@todo.context_id}items"
page.visual_effect :highlight, dom_id(@todo), :duration => 3
end
else
page.replace dom_id(@todo), :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@todo), :duration => 3
end
elsif source_view_is :stats
page.replace dom_id(@todo), :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@todo), :duration => 3
elsif source_view_is :calendar
if @due_date_changed
page[@todo].remove
page.show "empty_"+@original_item_due_id if @old_due_empty
page.hide "empty_"+@new_due_id
page.insert_html :bottom, @new_due_id, :partial => 'todos/todo', :locals => {:todo => @todo}
page.visual_effect :highlight, dom_id(@todo), :duration => 3
else
if @todo.due.nil?
# due date removed
page[@todo].remove
page.show "empty_"+@original_item_due_id if @old_due_empty
else
page.replace dom_id(@todo), :partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type }
page.visual_effect :highlight, dom_id(@todo), :duration => 3
end
end
else
logger.error "unexpected source_view '#{params[:_source_view]}'"
animation = []
animation << "remove_todo" if update_needs_to_remove_todo_from_container
if replace_with_updated_todo
animation << "replace_todo"
elsif append_updated_todo
animation << (@new_context_created ? "insert_new_context_with_updated_todo" : "add_to_existing_container")
end
# Update predecessors (if they exist and are visible)
@todo.uncompleted_predecessors.each do |p|
page << "if ($(\'#{item_container_id(p)}\')) {"
page[p].replace_html :partial => 'todos/todo',
:locals => { :todo => p, :parent_container_type => parent_container_type }
page << "}"
end
else
page.show 'error_status'
page.replace_html 'error_status', "#{error_messages_for('todo')}"
end
animation << "hide_context" if update_needs_to_hide_context
page << "enable_rich_interaction();"
# update relevant empty messaged
source_view do |page|
page.context {
animation << "show_empty_message_source_container" if (@remaining_in_context == 0)
}
page.project {
animation << "show_empty_message_project" if (@down_count == 0)
if @todo_was_activated_from_deferred_state
animation << "show_empty_message_tickler" if @deferred_count == 0
animation << "hide_empty_message_project"
end
animation << "hide_empty_message_tickler" if @todo_was_deferred && (@deferred_count == 1)
}
page.deferred {
animation << "show_empty_message_source_container" if (@remaining_in_context == 0)
animation << "hide_empty_message_target_container" if (@context_changed && @target_context_count==1)
}
page.calendar {
animation << "show_empty_message_source_container" if @old_due_empty
animation << "hide_empty_message_target_container" if @todo.due
}
end
animation << "highlight_updated_todo"
%>
<%= render_animation(animation) %>
TracksPages.page_notify('notice', '<%=@status_message%>', 5);
update_badge_count();
<% end %>
function remove_todo(next_steps) {
$('#<%= dom_id(@todo) %>').fadeOut(400, function() {
$('#<%= dom_id(@todo) %>').remove();
next_steps.go();
});
}
function replace_todo(next_steps) {
$('#<%= dom_id(@todo) %>').html(html_for_todo());
next_steps.go();
}
function hide_context(next_steps) {
<% context_id = @context_changed ? @original_item_context_id : @todo.context_id -%>
$('#c<%= context_id %>').fadeOut(400, function(){ next_steps.go(); });
}
function highlight_updated_todo(next_steps) {
$('#<%= dom_id(@todo)%>').effect('highlight', {}, 2000, function(){ next_steps.go(); });
}
function add_to_existing_container(next_steps) {
$('#<%= item_container_id(@todo) %>').append(html_for_todo());
<% if source_view_is_one_of(:project,:calendar) -%>
next_steps.go();
<% else -%>
$('#c<%= @todo.context_id %>').fadeIn(500, function() { next_steps.go(); });
<% end -%>
}
function update_badge_count() {
<%
count = source_view_is(:context) ? @remaining_in_context : @down_count
count = @project_changed ? @remaining_undone_in_project : count
-%>
TracksPages.set_page_badge(<%= count %>);
}
function show_empty_message_source_container(next_steps) {
<% container_id = source_view_is(:calendar) ? "empty_#{@original_item_due_id}" : "c#{@original_item_context_id}empty-nd" -%>
$("#<%= container_id%>").slideDown(100, function() { next_steps.go(); });
}
function hide_empty_message_target_container(next_steps) {
<% container_id = source_view_is(:calendar) ? "empty_#{@new_due_id}" : "c#{@todo.context_id}empty-nd" -%>
$("#<%=container_id%>").slideUp(100, function() { next_steps.go(); });
}
function show_empty_message_project(next_steps) {<%
id = updated_todo_changed_deferred_state ? "p#{@todo.project_id}empty-nd" : empty_container_msg_div_id %>
$('#<%= id %>').slideDown(100, function() { next_steps.go(); });
}
function hide_empty_message_project(next_steps) {
$('#<%= empty_container_msg_div_id %>').slideUp(100, function() { next_steps.go(); });
}
function show_empty_message_tickler(next_steps) {
$('#tickler-empty-nd').slideDown(100, function() { next_steps.go(); });
}
function hide_empty_message_tickler(next_steps) {
$('#tickler-empty-nd').slideUp(100, function(){ next_steps.go(); });
}
function insert_new_context_with_updated_todo(next_steps) {
$('#display_box').prepend(html_for_new_context());
$('#c<%= @todo.context_id %>').fadeIn(500, function() { next_steps.go(); });
}
function html_for_todo() {
return "<%= @saved ? escape_javascript(render(:partial => 'todos/todo', :locals => { :todo => @todo, :parent_container_type => parent_container_type })) : "" %>";
}
function html_for_new_context() {
return "<%= @saved && @new_context_created ? escape_javascript(render(:partial => 'contexts/context', :locals => { :context => @new_context, :collapsible => true })) : "" %>";
}
function html_for_error_messages() {
return "<%= escape_javascript(error_messages_for('todo')) %>";
}
function update_predecessors() {
<% @todo.uncompleted_predecessors.each do |p| -%>
if ($('#<%=item_container_id(p)%>')) {
$('#<%=dom_id(p)%>').html('<%=escape_javascript(render(:partial => 'todos/todo', :locals => { :todo => p, :parent_container_type => parent_container_type }))%>');
}
<% end -%>
}