Mostly worked on the candidate adding feature to include pictures and
author<mako@atdot.cc> <>
Thu, 17 Aug 2006 21:16:15 +0000 (17:16 -0400)
committer<mako@atdot.cc> <>
Thu, 17 Aug 2006 21:16:15 +0000 (17:16 -0400)
haev a better interface.

15 files changed:
app/controllers/election_controller.rb
app/models/candidate.rb
app/views/election/_candidate_form.rhtml [new file with mode: 0644]
app/views/election/_candidate_line.rhtml
app/views/election/_candidate_line_edit.rhtml [new file with mode: 0644]
app/views/election/_candidate_list.rhtml
app/views/election/_candidates_form.rhtml
app/views/election/_voter_list.rhtml
app/views/election/edit_candidate.rhtml [new file with mode: 0644]
app/views/election/edit_candidates.rhtml
app/views/election/new_candidates.rhtml [deleted file]
app/views/election/show.rhtml
app/views/site/_user_summary.rhtml
db/create.sql
public/stylesheets/vb.css

index f4b89b40cb9c291e41443c1bdf73f502589d4e1e..a0549d40d510fabb9abd71e223a528a29879be48 100644 (file)
@@ -22,7 +22,7 @@ class ElectionController < ApplicationController
 
     if @election.save
       flash[:notice] = 'Election was successfully created.'
-      redirect_to :action => 'new_candidates', :id => @election.id
+      redirect_to :action => 'edit_candidates', :id => @election.id
     else
       render :action => 'new'
     end
@@ -56,19 +56,21 @@ class ElectionController < ApplicationController
   # methods fod display, adding, deleting, and manipulating candidate
   # information for elections
   ####################################################################
-  def new_candidates
+  def edit_candidates
     @election = Election.find( params[:id] )
   end
 
   def add_candidate
-    election = Election.find( params[:id] )
-    @candidate = Candidate.new
-    @candidate.name = params[:newcandidate][:name]
-    @candidate.description = params[:newcandidate][:description]
+    @election = Election.find(params[:id])
+    @candidate = Candidate.new(params[:candidate])
     
-    @candidate.save
-    election.candidates << @candidate
-    render :partial => 'candidate_line'
+    if @candidate.save
+      @election.candidates << @candidate
+      @candidate = Candidate.new
+      redirect_to :action => 'edit_candidates', :id => @election.id
+    else
+      render :action => 'edit_candidates', :id => @election.id
+    end
   end
   
   def delete_candidate
@@ -76,8 +78,40 @@ class ElectionController < ApplicationController
     candidate.destroy
   end
 
-  def edit_candidates
-    @election = Election.find( params[:id] )
+  def lessinfo_candidate
+    @show_details = false
+    @candidate = Candidate.find( params[:id] )
+    render :partial => 'candidate_line'
+  end
+
+  def moreinfo_candidate
+    @show_details = true
+    @candidate = Candidate.find( params[:id] )
+    render :partial => 'candidate_line'
+  end
+
+  def edit_candidate
+    @candidate = Candidate.find( params[:id] )
+    @election = @candidate.election
+  end
+
+  def update_candidate
+    @candidate = Candidate.find(params[:id])
+
+    if @candidate.update_attributes(params[:candidate])
+      flash[:notice] = 'Candidate information was successfully updated.'
+      redirect_to :action => 'edit_candidates', :id => @candidate.election
+    else
+      render :action => 'edit_candidates'
+    end
+  end
+
+  def candidate_picture
+    candidate = Candidate.find( params[:id] )
+    send_data( candidate.picture_data,
+               :filename => candidate.picture_filename,
+              :type => candidate.picture_type,
+              :disposition => 'inline' )
   end
 
   ## methods for displaying, adding, deleting, and manipulating voters
index e17ba29b5f1ff866e3dd3c0d9c26beaa5b105aa5..7af978afb3f95e422d035b780f4e4519f7fb8021 100644 (file)
@@ -1,5 +1,6 @@
 class Candidate < ActiveRecord::Base
   belongs_to :election
+  validates_uniqueness_of :name
 
   def <=>(other)
     self.name <=> other.name 
@@ -9,4 +10,25 @@ class Candidate < ActiveRecord::Base
     name
   end
 
+  def picture=(picture_field)
+    if picture_field
+      unless picture_field.content_type.match(/^image/)
+        return false
+      end
+      self.picture_filename = base_part_of(picture_field.original_filename)
+      self.picture_type =  picture_field.content_type.chomp
+      self.picture_data = picture_field.read
+    end
+  end
+
+  def base_part_of(filename)
+    name = File.basename(filename)
+    name.gsub(/[^\w._-]/, '')
+  end
+
+  def picture?
+    !self.picture_filename.nil?
+  end
+
 end
+
diff --git a/app/views/election/_candidate_form.rhtml b/app/views/election/_candidate_form.rhtml
new file mode 100644 (file)
index 0000000..e9770b8
--- /dev/null
@@ -0,0 +1,8 @@
+<p>New candidate name:<br />
+<%= text_field :candidate, :name %></p>
+<p>Candidate description/platform (optional):<br />
+<%= text_area :candidate, :description %></p>
+
+<p>Candidate picture (optional and < 100x100 pixels):<br />
+<%= file_field :candidate, :picture %></p>
index 7f68e6fa60b1177abdf5c4d59524da29db4618db..5145b88878e78add5767e0890644ac76b94cbaad 100644 (file)
@@ -1,11 +1,19 @@
-<div id="cand<%= @candidate.id %>">
-  <li>
-    <%= @candidate.name %>
-    <% if @edit %>
-      <%= link_to_remote "Delete",
-                         :complete => "Element.remove('cand#{@candidate.id}')",
-                        :url => { :action => :delete_candidate, :id => @candidate.id } %>
+<% -%>
+<div id="cand<%= @current_candidate.id %>">
+  <li><%= @current_candidate.name -%>
+    <% if @show_details %>
+      (<%= link_to_remote "Hide Details",
+                         :update => "cand#{@current_candidate.id}",
+                         :url => { :action => :lessinfo_candidate, :id => @current_candidate.id } %>)
+      <br />
+      <blockquote>
+      <%= h(@current_candidate.description) %>
+      </blockquote>
+    <% else %>
+      (<%= link_to_remote "Show Details",
+                         :update => "cand#{@current_candidate.id}",
+                         :url => { :action => :moreinfo_candidate,
+                        :id => @current_candidate.id } %>)
     <% end %>
-
   </li>
 </div>
diff --git a/app/views/election/_candidate_line_edit.rhtml b/app/views/election/_candidate_line_edit.rhtml
new file mode 100644 (file)
index 0000000..ea20a4f
--- /dev/null
@@ -0,0 +1,24 @@
+<% -%>
+<div id="cand<%= @current_candidate.id %>">
+<p><strong><%= @current_candidate.name %></strong>
+  (<%= link_to_remote "Delete",
+                       :complete => "Element.remove('cand#{@current_candidate.id}')",
+                       :url => { :action => :delete_candidate,
+                      :id => @current_candidate.id } %> |
+    <%= link_to "Edit", :action => 'edit_candidate', :id =>
+    @current_candidate.id %>)<br />
+    <blockquote>
+    <table><tr><td valign="top">
+      <% if @current_candidate.picture? %>
+      <img src="<%= url_for :action => 'candidate_picture',
+                            :id => @current_candidate.id %>"
+           align="top" />
+      <% end %>
+      </td>
+      <td valign="top">
+        <em>Description:</em><br />
+         <%= h(@current_candidate.description) %>
+    </td></tr></table>
+    </blockquote>
+</p>
+</div>
index ca8a5cc4d9e0a940f593418db15d6390200fdef9..74d4c3c96016fbac4718169f230896854e060f13 100644 (file)
@@ -1,7 +1,7 @@
 <% %>
 <ul id="candidate_list">
   <% @election.candidates.each do |candidate| %>
-    <% @candidate = candidate %>
+    <% @current_candidate = candidate %>
       <%= render :partial => 'candidate_line' %>
     <% end %>
 </ul>
index ca6e73ed91e9478c3dfb147a07fe2e83c1809884..452892340e55aaa1347567a17dc555b058700d95 100644 (file)
@@ -1,15 +1,9 @@
 <% %>
-<p>Please enter candidates for <strong><%= @election.name %></strong>.</p>
 
-<%= form_remote_tag(:update => "candidate_list",
-                    :url => { :action => :add_candidate, :id => @election.id },
-                    :position => "bottom" ) %>
+<%= form_tag( { :action => :add_candidate, :id => @election.id },
+              :multipart => true ) %>
 
-<p>New candidate name:<br />
-<%= text_field :newcandidate, :name %></p>
-<p>Candidate description/platform (optional):<br />
-<%= text_area :newcandidate, :description %></p>
+<%= render_partial 'candidate_form' %>
 
 <%= submit_tag "Add Candidate" %>
 <%= end_form_tag %>
index c1035d7a9491b611be7584980be9ea705a4c2e8d..2a39b8cf4f3199a2568cd26e5e682e08979c9b9f 100644 (file)
@@ -1,23 +1,19 @@
 <%
 # basic election information template
 -%>
+<p>The following voters are currently registered for this election:</p>
 
-<% unless @election.voters.empty? %>
-  <p>The following voters are currently registered for this election:</p>
-
-  <ul>
-    <% @election.voters.each do |voter| %>
-    <div id="voter<%= voter.id %>">
-      <li><%= voter.email %>
-          <% if @edit %>
-          <%= link_to_remote "Delete",
-                      :complete => "Element.remove('voter#{voter.id}')",
-                     :url => { :action => :delete_voter, :id => voter.id } %>
-         <% end %>
-      </li>
-    </div>  
-    <% end %>
-  </ul>
-<% end %>
-
+<ul>
+  <% @election.voters.each do |voter| %>
+  <div id="voter<%= voter.id %>">
+    <li><%= voter.email %>
+        <% if @edit %>
+        <%= link_to_remote "Delete",
+                    :complete => "Element.remove('voter#{voter.id}')",
+                    :url => { :action => :delete_voter, :id => voter.id } %>
+        <% end %>
+    </li>
+  </div>  
+  <% end %>
+</ul>
 
diff --git a/app/views/election/edit_candidate.rhtml b/app/views/election/edit_candidate.rhtml
new file mode 100644 (file)
index 0000000..9bc9954
--- /dev/null
@@ -0,0 +1,9 @@
+<h1>Editing <%= @candidate.name %></h1>
+
+<%= error_messages_on :candidate %>
+
+<%= form_tag :action => 'update_candidate', :id => @candidate.id %>
+  <%= render :partial => 'candidate_form' %>
+  <%= submit_tag "Done!" %>
+<%= end_form_tag %>
+
index 0c416d5ee071cb757a11c9b3ff73e10869b23333..b5f06ff31856dd1e0822ed12cf5388f353a7509f 100644 (file)
@@ -1,14 +1,16 @@
-<% @edit = true %>
 <h1><strong><%= @election.name %>:</strong> Edit Candidates</h1>
 
-<p>The following are valid options or candidates in this election:</p>
+<% unless @election.candidates.empty? %>
+  <p>The following are valid options or candidates in this election:</p>
 
-<ul>
-<% @election.candidates.each do |candidate| %>
-   <% @candidate = candidate %>
-   <%= render :partial => 'candidate_line' %>
-<% end %>
-</ul>
+  <% @election.candidates.each do |candidate| %>
+    <% @current_candidate = candidate %>
+    <%= render :partial => 'candidate_line_edit' %>
+  <% end %>
 
+<% else %>
+  <p>There are no candidates registered for this election.</p>
+<% end %>
+<p>Please enter new candidates below.</p>
 <%= render :partial => 'candidates_form' %>
 <%= button_to "Done!", :action => 'show', :id => @election %>
diff --git a/app/views/election/new_candidates.rhtml b/app/views/election/new_candidates.rhtml
deleted file mode 100644 (file)
index f95cd83..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-<% @edit = true %>
-<h1><strong><%= @election.name %></strong> Candidates</h1>
-
-<ul id="candidate_list">
-<% for candidate in @election.candidates %>
-  <li><%= candidate.name %></li>
-<% end %>
-</ul>
-
-<%= render :partial => 'candidates_form' %>
-<%= button_to "Done!", :action => 'show', :id => @election %>
index 954e480e4b9b2ac1c35340d135805483f5beb29e..f389059d72436e9539c391860d6e6f18b8674bfb 100644 (file)
@@ -1,18 +1,38 @@
 <% %>
 <h1>Information On <%= @election.name %></h1>
 
-<h2>Overview <%= link_to "edit", :action => 'edit', :id => @election.id %></h2> 
-
+<h2>Election Overview</h2> 
 <p><strong>Description</strong></p>
 
 <blockquote>
-<%= @election.description %>
+<%= h(@election.description) %>
 </blockquote>
 
-<h2>Candidates <%= link_to "edit", :action => 'edit_candidates', :id => @election.id %></h2> 
+<p><strong>Election End Date</strong></p>
+
+<blockquote>
+<%= @election.enddate %>
+</blockquote>
+
+<p><%= link_to "Edit election overview.", :action => 'edit', :id => @election.id %></p>
+
+<h2>Candidates</h2> 
+
+<% unless @election.candidates.empty? %>
+  <%= render :partial => 'candidate_list' %>
+  <p><%= link_to "Add, remove, or edit candidates.", :action => 'edit_candidates', :id => @election.id %></p>
+<% else %>
+  <p><em>There are currently no candidates registered for this election.
+  <%= link_to "Add some!", :action => 'edit_candidates', :id => @election.id %></em></p>
 
-<%= render :partial => 'candidate_list' %>
+<% end %>
 
-<h2>Voters <%= link_to "edit", :action => 'edit_voters', :id => @election.id %></h2>
+<h2>Voters</h2>
 
-<%= render :partial => 'voter_list' %>
+<% unless @election.voters.empty? %>
+  <%= render :partial => 'voter_list' %>
+<% else %>
+  <p><em>There are currently no voters registered for this election.
+  <%= link_to "Add some!", :action => 'edit_voters', :id => @election.id %></em></p>
+<% end %>
index a23149794caed1a3c853b8d14d91ef3a260dd80e..310d98cb6fe37a3f5701e85e3595d35902e2b3c1 100644 (file)
@@ -7,7 +7,8 @@
 <% else %>
   <ul>
   <% for election in @current_elections %>
-    <li><%= election.name %> (ends <em><%= election.enddate %></em>)</li> 
+    <li><%= link_to election.name, :controller => 'election', :action => 'show', :id => election.id %> (ends in <em><%=
+    distance_of_time_in_words Time.now, election.enddate %></em>)</li> 
   <% end %>
   </ul>
 <% end %>
index 4a2025f01ff542b820f699d40b5d48ad0586eae8..bbc054ae19ac33601dc5ab6709fc0a630a71c71c 100644 (file)
@@ -1,18 +1,3 @@
-# CREATE users TABLE
-#####################################
-
-#drop table if exists users;
-#create table users (
-# id int NOT NULL auto_increment,
-# login varchar(80) default NULL,
-# password varchar(40) default NULL,
-# primary key (id)
-#);
-
-## Create a default system user to own stage directions
-## and similar. Users cannot log in.
-#insert into users ( id, login ) values ( 1, "System Defaults" );
-
 # CREATE elections TABLE
 #####################################
 
@@ -21,9 +6,10 @@ create table elections (
  id int NOT NULL auto_increment,
  name varchar(100) NOT NULL, 
  description TEXT NOT NULL, 
- anonymous tinyint NOT NULL DEFAULT 0, 
- startdate datetime NOT NULL, 
- enddate datetime, 
+ anonymous tinyint NOT NULL DEFAULT 1, 
+ startdate datetime, 
+ enddate datetime NOT NULL, 
+ active tinyint NOT NULL DEFAULT 0,
  user_id int NOT NULL,
  primary key (id),
  constraint fk_user_election foreign key (user_id) references users(id)
@@ -38,7 +24,9 @@ create table candidates (
  election_id int NOT NULL,
  name varchar(100) NOT NULL, 
  description text NULL,
- picture blob NOT NULL, 
+ picture_filename varchar(200),
+ picture_data blob, 
+ picture_type varchar(100), 
  primary key (id)
 );
 
index a054b855ac1ba508c7f75c807a9eb2d40d15ebcd..176fd28efd98a09f592b0ac78ec0c6d38b77240e 100644 (file)
@@ -99,7 +99,5 @@ a:active { color: #FFFFFF; text-decoration: none; background: #0259C4; }
 #subtext { 
        text-align: center;
        font-size: 12px;
-       font-weight: bold;
-       
-}
+       font-weight: bold; }
 

Benjamin Mako Hill || Want to submit a patch?