mirror of
https://github.com/TracksApp/tracks.git
synced 2026-01-30 20:55:17 +01:00
Tried out using a modal 'lightbox' style dialog for the new next action form on the home page (I'm using the scripts written by Bruno of [http://blog.feedmarker.com/2006/02/12/how-to-make-better-modal-windows-with-lightbox/ Feedmarker]).
Instead of opening up a form on the main page, clicking the 'Add new action' link (or hitting Alt/Ctrl N) opens up an overlay window, with a semi-transparent window underneath. You can add as many actions as you like by filling in the forms and hitting submit, then when you're done, click the close box or the shaded overlay area to dismiss the window. It works very well on Safari, but for some reason, on my copy of Firefox, the cursor is invisible. My plan is to also allow deferred actions to be added using this form, and eventually set up editing of existing actions to use the same format. git-svn-id: http://www.rousette.org.uk/svn/tracks-repos/trunk@250 a4c988fc-2ded-0310-b66e-134b36920a42
This commit is contained in:
parent
f10e5b102e
commit
3da6fe2525
11 changed files with 239 additions and 11 deletions
|
|
@ -61,7 +61,8 @@ class TodoController < ApplicationController
|
|||
|
||||
@on_page = "home"
|
||||
if @saved
|
||||
@up_count = @todos.collect { |x| ( !x.done? and !x.context.hide? ) ? x:nil }.compact.size.to_s
|
||||
self.init # we have to do this again to update @todos
|
||||
@up_count = @todos.reject { |x| x.done? or x.context.hide? }.size.to_s
|
||||
end
|
||||
return if request.xhr?
|
||||
|
||||
|
|
@ -202,7 +203,8 @@ class TodoController < ApplicationController
|
|||
@saved = @item.destroy
|
||||
@on_page = "home"
|
||||
if @saved
|
||||
@down_count = @todos.collect { |x| ( !x.done? and !x.context.hide? ) ? x:nil }.compact.size.to_s
|
||||
self.init
|
||||
@down_count = @todos.reject { |x| x.done? or x.context.hide? }.size.to_s
|
||||
end
|
||||
|
||||
return if request.xhr?
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@
|
|||
<%= javascript_include_tag 'calendar', 'calendar-en', 'calendar-setup' %>
|
||||
<%= javascript_include_tag "accesskey-hints" %>
|
||||
<%= javascript_include_tag "todo-items" %>
|
||||
<%= javascript_include_tag "lightbox" %>
|
||||
<%= stylesheet_link_tag "lightbox" %>
|
||||
|
||||
<link rel="shortcut icon" href="<%= url_for(:controller => 'favicon.ico') %>" />
|
||||
<%= auto_discovery_link_tag(:rss,{:controller => "feed", :action => "na_feed", :name => "#{@user.login}", :token => "#{@user.word}"}, {:title => "RSS feed of next actions"}) %>
|
||||
|
|
|
|||
48
tracks/app/views/shared/_new_action_form.rhtml
Normal file
48
tracks/app/views/shared/_new_action_form.rhtml
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
<div id="mybox" style="display:none">
|
||||
<div id="todo_new_action" class="context_new">
|
||||
<%= form_remote_tag(
|
||||
:url => { :controller => controller.controller_name, :action => "add_item" },
|
||||
:html=> { :id=>'todo-form-new-action', :name=>'todo', :class => 'inline-form' }) %>
|
||||
|
||||
<h2>Add a new next action:</h2>
|
||||
<div id="status">
|
||||
</div>
|
||||
<table>
|
||||
<tr>
|
||||
<td><label for="todo_description">Description</label></td>
|
||||
<td><%= text_field( "todo", "description", "size" => 30, "tabindex" => 1) %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="todo_notes">Notes</label></td>
|
||||
<td><%= text_area( "todo", "notes", "cols" => 25, "rows" => 10, "tabindex" => 2) %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="todo_context_id">Context</label></td>
|
||||
<td><%= collection_select( "todo", "context_id", @contexts, "id", "name",
|
||||
{}, {"tabindex" => 3}) %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="todo_project_id">Project</label></td>
|
||||
<td><%= collection_select( "todo", "project_id", @projects.reject{|p| p.done?}, "id", "name",
|
||||
{ :include_blank => true }, {"tabindex" => 4}) %></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label for="todo_due">Due</label></td>
|
||||
<td><%= text_field("todo", "due", "size" => 10, "class" => "Date", "onFocus" => "Calendar.setup", "tabindex" => 5, "autocomplete" => "off") %></td>
|
||||
</tr>
|
||||
|
||||
<% if controller.controller_name == "project" -%>
|
||||
<%= hidden_field( "todo", "project_id", "value" => "#{@project.id}") %>
|
||||
<% elsif controller.controller_name == "context" -%>
|
||||
<%= hidden_field( "todo", "context_id", "value" => "#{@context.id}") %>
|
||||
<% end -%>
|
||||
|
||||
<tr>
|
||||
<td></td>
|
||||
<td><input type="submit" value="Add item" tabindex="6"></td>
|
||||
</tr>
|
||||
</table>
|
||||
<%= end_form_tag %><!--[eoform:todo]-->
|
||||
<%= calendar_setup( "todo_due" ) %>
|
||||
</div><!-- [end:todo-new-action] -->
|
||||
</div>
|
||||
|
|
@ -1,6 +1,6 @@
|
|||
<h3>Active Projects:</h3>
|
||||
<ul>
|
||||
<% for project in @projects.reject{|p| p.done } -%>
|
||||
<% for project in @projects.reject{|p| p.done? } -%>
|
||||
<li><%= link_to( sanitize(project.name), { :controller => "project", :action => "show",
|
||||
:name => urlize(project.name) } ) + " (" + project.count_undone_todos("actions") + ")" %></li>
|
||||
<% end -%>
|
||||
|
|
@ -8,7 +8,7 @@
|
|||
|
||||
<h3>Completed Projects:</h3>
|
||||
<ul>
|
||||
<% for project in @projects.reject{|p| !p.done } -%>
|
||||
<% for project in @projects.reject{|p| !p.done? } -%>
|
||||
<li><%= link_to( sanitize(project.name), { :controller => "project", :action => "show",
|
||||
:name => urlize(project.name) } ) + " (" + project.count_undone_todos("actions") + ")" %></li>
|
||||
<% end -%>
|
||||
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
<h3>Active Contexts:</h3>
|
||||
<ul>
|
||||
<% for context in @contexts.reject{|c| c.hide } -%>
|
||||
<% for context in @contexts.reject{|c| c.hide? } -%>
|
||||
<li><%= link_to( sanitize(context.name), { :controller => "context", :action => "show",
|
||||
:name => urlize(context.name) } ) + " (" + context.count_undone_todos("actions") + ")" %></li>
|
||||
<% end -%>
|
||||
|
|
@ -24,7 +24,7 @@
|
|||
|
||||
<h3>Hidden Contexts:</h3>
|
||||
<ul>
|
||||
<% for context in @contexts.reject{|c| !c.hide } -%>
|
||||
<% for context in @contexts.reject{|c| !c.hide? } -%>
|
||||
<li><%= link_to( sanitize(context.name), { :controller => "context", :action => "show",
|
||||
:name => urlize(context.name) } ) + " (" + context.count_undone_todos("actions") + ")" %></li>
|
||||
<% end -%>
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
if @saved
|
||||
page.hide "status"
|
||||
page.show "status"
|
||||
page.replace_html "status", content_tag("div", "Added new next action", "class" => "confirmation")
|
||||
page.visual_effect :appear, 'status', :duration => 0.5
|
||||
page.replace_html "badge_count", @up_count
|
||||
page.visual_effect :fade, 'status', :duration => 2
|
||||
page['badge_count'].replace_html @up_count
|
||||
page.send :record, "Form.reset('todo-form-new-action');Form.focusFirstElement('todo-form-new-action')"
|
||||
page.insert_html :bottom, "c#{@item.context_id}items", :partial => 'todo/item'
|
||||
page.visual_effect :highlight, "item-#{@item.id}-container", :duration => 3
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@
|
|||
</div><!-- End of display_box -->
|
||||
|
||||
<div id="input_box">
|
||||
<%= render :partial => "shared/add_new_item_form", :locals => {:hide_link => false, :msg => ""} %>
|
||||
<a href="#" onclick="new Lightbox.base('mybox', { closeOnOverlayClick : true });Form.focusFirstElement('todo-form-new-action'); return false" accesskey="n">Add new action »</a>
|
||||
<%= render :partial => "shared/new_action_form" %>
|
||||
<%= render "shared/sidebar" %>
|
||||
</div><!-- End of input box -->
|
||||
BIN
tracks/public/images/close.gif
Normal file
BIN
tracks/public/images/close.gif
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 109 B |
130
tracks/public/javascripts/lightbox.js
Executable file
130
tracks/public/javascripts/lightbox.js
Executable file
|
|
@ -0,0 +1,130 @@
|
|||
/*--------------------------------------------------------------------------*/
|
||||
/* Lightbox
|
||||
* This is a script for creating modal dialog windows (like the ones your operating
|
||||
* system uses)
|
||||
*
|
||||
*/
|
||||
|
||||
var Lightbox = {
|
||||
/* hideAll - closes all open lightbox windows */
|
||||
hideAll: function(){
|
||||
lboxes = document.getElementsByClassName('lbox')
|
||||
lboxes.each(function(box){
|
||||
Element.hide(box)
|
||||
}
|
||||
)
|
||||
if ($('overlay')){
|
||||
Element.remove('overlay');
|
||||
}
|
||||
}
|
||||
}
|
||||
Lightbox.base = Class.create();
|
||||
Lightbox.base.prototype = {
|
||||
|
||||
initialize: function(element, options){
|
||||
//start by hiding all lightboxes
|
||||
Lightbox.hideAll();
|
||||
|
||||
this.element = $(element);
|
||||
this.options = Object.extend({
|
||||
lightboxClassName : 'lightbox',
|
||||
closeOnOverlayClick : false,
|
||||
externalControl : false
|
||||
}, options || {} )
|
||||
|
||||
//create the overlay
|
||||
new Insertion.Before(this.element, "<div id='overlay' style='display:none;'></div>");
|
||||
|
||||
Element.addClassName(this.element, this.options.lightboxClassName)
|
||||
|
||||
//also add a default lbox class to the lightbox div so we can find and close all lightboxes if we need to
|
||||
Element.addClassName(this.element, 'lbox')
|
||||
|
||||
//Tip: make sure the path to the close.gif image below is correct for your setup
|
||||
closer = '<img id="close" src="/images/close.gif" alt="Close" title="Close this window" />'
|
||||
|
||||
//insert the closer image into the div
|
||||
new Insertion.Top(this.element, closer);
|
||||
|
||||
Event.observe($('close'), 'click', this.hideBox.bindAsEventListener(this) );
|
||||
|
||||
if (this.options.closeOnOverlayClick){
|
||||
Event.observe($('overlay'), 'click', this.hideBox.bindAsEventListener(this) );
|
||||
}
|
||||
if (this.options.externalControl){
|
||||
Event.observe($(this.options.externalControl), 'click', this.hideBox.bindAsEventListener(this) );
|
||||
}
|
||||
|
||||
this.showBox();
|
||||
},
|
||||
|
||||
showBox : function(){
|
||||
//show the overlay
|
||||
Element.show('overlay');
|
||||
|
||||
//center the lightbox
|
||||
this.center();
|
||||
|
||||
//show the lightbox
|
||||
Element.show(this.element);
|
||||
return false;
|
||||
},
|
||||
|
||||
hideBox : function(evt){
|
||||
Element.removeClassName(this.element, this.options.lightboxClassName)
|
||||
Element.hide(this.element);
|
||||
//remove the overlay element from the DOM completely
|
||||
Element.remove('overlay');
|
||||
return false;
|
||||
},
|
||||
|
||||
center : function(){
|
||||
var my_width = 0;
|
||||
var my_height = 0;
|
||||
|
||||
if ( typeof( window.innerWidth ) == 'number' ){
|
||||
my_width = window.innerWidth;
|
||||
my_height = window.innerHeight;
|
||||
}else if ( document.documentElement &&
|
||||
( document.documentElement.clientWidth ||
|
||||
document.documentElement.clientHeight ) ){
|
||||
my_width = document.documentElement.clientWidth;
|
||||
my_height = document.documentElement.clientHeight;
|
||||
}
|
||||
else if ( document.body &&
|
||||
( document.body.clientWidth || document.body.clientHeight ) ){
|
||||
my_width = document.body.clientWidth;
|
||||
my_height = document.body.clientHeight;
|
||||
}
|
||||
|
||||
this.element.style.position = 'absolute';
|
||||
this.element.style.zIndex = 99;
|
||||
|
||||
var scrollY = 0;
|
||||
|
||||
if ( document.documentElement && document.documentElement.scrollTop ){
|
||||
scrollY = document.documentElement.scrollTop;
|
||||
}else if ( document.body && document.body.scrollTop ){
|
||||
scrollY = document.body.scrollTop;
|
||||
}else if ( window.pageYOffset ){
|
||||
scrollY = window.pageYOffset;
|
||||
}else if ( window.scrollY ){
|
||||
scrollY = window.scrollY;
|
||||
}
|
||||
|
||||
var elementDimensions = Element.getDimensions(this.element);
|
||||
|
||||
var setX = ( my_width - elementDimensions.width ) / 2;
|
||||
var setY = ( my_height - elementDimensions.height ) / 2 + scrollY;
|
||||
|
||||
setX = ( setX < 0 ) ? 0 : setX;
|
||||
setY = ( setY < 0 ) ? 0 : setY;
|
||||
|
||||
this.element.style.left = setX + "px";
|
||||
this.element.style.top = setY + "px";
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -8,6 +8,7 @@ div.calendar { position: relative; }
|
|||
color: #000;
|
||||
cursor: default;
|
||||
background: #eef;
|
||||
z-index: 110;
|
||||
font-family: tahoma,verdana,sans-serif;
|
||||
}
|
||||
|
||||
|
|
|
|||
44
tracks/public/stylesheets/lightbox.css
Executable file
44
tracks/public/stylesheets/lightbox.css
Executable file
|
|
@ -0,0 +1,44 @@
|
|||
/*body {
|
||||
font-family:arial, helvetica, sans-serif;
|
||||
}
|
||||
*/
|
||||
#overlay{
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
width:100%;
|
||||
height:100%;
|
||||
z-index:80;
|
||||
background-color:#000;
|
||||
-moz-opacity: 0.8;
|
||||
opacity:.80;
|
||||
filter: alpha(opacity=80);
|
||||
}
|
||||
#overlay[id]{ /* IE6 and below Can't See This */
|
||||
position:fixed;
|
||||
}
|
||||
|
||||
|
||||
.lightbox{
|
||||
width:350px;
|
||||
background:#eee;
|
||||
padding:10px;
|
||||
border:2px solid #666;
|
||||
}
|
||||
|
||||
.lightbox h2 {
|
||||
background-color: #666;
|
||||
color: #fff !important;
|
||||
margin-left: -10px;
|
||||
margin-right: -5px;
|
||||
margin-top: -10px;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
#close{
|
||||
position:absolute;
|
||||
top:-5px;
|
||||
right:-5px;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
|
|
@ -308,7 +308,7 @@ a.footer_link:hover {color: #fff; background-color: #cc3334 !important;}
|
|||
}
|
||||
|
||||
#status .confirmation {
|
||||
width: 220px;
|
||||
margin: 2px 5px;
|
||||
}
|
||||
#warning, .warning {
|
||||
padding: 2px;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue