Commit 12122b7ecebaaaca01b315854ea29447b91a2366
1 parent
76ea5e7a
Exists in
master
and in
1 other branch
Make nested watcher form more user friendly
Showing
5 changed files
with
53 additions
and
8 deletions
Show diff stats
app/models/app.rb
@@ -16,9 +16,10 @@ class App | @@ -16,9 +16,10 @@ class App | ||
16 | validates_presence_of :name, :api_key | 16 | validates_presence_of :name, :api_key |
17 | validates_uniqueness_of :name, :allow_blank => true | 17 | validates_uniqueness_of :name, :allow_blank => true |
18 | validates_uniqueness_of :api_key, :allow_blank => true | 18 | validates_uniqueness_of :api_key, :allow_blank => true |
19 | + validates_associated :watchers | ||
19 | 20 | ||
20 | accepts_nested_attributes_for :watchers, :allow_destroy => true, | 21 | accepts_nested_attributes_for :watchers, :allow_destroy => true, |
21 | - :reject_if => proc { |attrs| attrs.all? { |k, v| v.blank? } } | 22 | + :reject_if => proc { |attrs| attrs[:user_id].blank? && attrs[:email].blank? } |
22 | 23 | ||
23 | # Mongoid Bug: find(id) on association proxies returns an Enumerator | 24 | # Mongoid Bug: find(id) on association proxies returns an Enumerator |
24 | def self.find_by_id!(app_id) | 25 | def self.find_by_id!(app_id) |
app/models/watcher.rb
@@ -9,6 +9,14 @@ class Watcher | @@ -9,6 +9,14 @@ class Watcher | ||
9 | 9 | ||
10 | validate :ensure_user_or_email | 10 | validate :ensure_user_or_email |
11 | 11 | ||
12 | + before_validation :clear_unused_watcher_type | ||
13 | + | ||
14 | + attr_accessor :watcher_type | ||
15 | + | ||
16 | + def watcher_type | ||
17 | + @watcher_type ||= email.present? ? 'email' : 'user' | ||
18 | + end | ||
19 | + | ||
12 | def label | 20 | def label |
13 | user ? user.name : email | 21 | user ? user.name : email |
14 | end | 22 | end |
@@ -22,5 +30,14 @@ class Watcher | @@ -22,5 +30,14 @@ class Watcher | ||
22 | def ensure_user_or_email | 30 | def ensure_user_or_email |
23 | errors.add(:base, "You must specify either a user or an email address") unless user.present? || email.present? | 31 | errors.add(:base, "You must specify either a user or an email address") unless user.present? || email.present? |
24 | end | 32 | end |
33 | + | ||
34 | + def clear_unused_watcher_type | ||
35 | + case watcher_type | ||
36 | + when 'user' | ||
37 | + self.email = nil | ||
38 | + when 'email' | ||
39 | + self.user = self.user_id = nil | ||
40 | + end | ||
41 | + end | ||
25 | 42 | ||
26 | end | 43 | end |
app/views/apps/_fields.html.haml
@@ -11,11 +11,13 @@ | @@ -11,11 +11,13 @@ | ||
11 | %fieldset.nested-wrapper | 11 | %fieldset.nested-wrapper |
12 | %legend Watchers | 12 | %legend Watchers |
13 | - f.fields_for :watchers do |w| | 13 | - f.fields_for :watchers do |w| |
14 | - %div.nested | ||
15 | - %div | ||
16 | - = w.label :user | 14 | + %div.watcher.nested |
15 | + %div.choose | ||
16 | + = w.radio_button :watcher_type, :user | ||
17 | + = label_tag :watcher_type_user, 'User' | ||
18 | + = w.radio_button :watcher_type, :email | ||
19 | + = label_tag :watcher_type_email, 'Email Address' | ||
20 | + %div.user{:class => w.object.email.blank? ? 'choosen' : nil} | ||
17 | = w.select :user_id, User.all.map{|u| [u.name,u.id.to_s]}, :include_blank => '-- Select a User --' | 21 | = w.select :user_id, User.all.map{|u| [u.name,u.id.to_s]}, :include_blank => '-- Select a User --' |
18 | - %strong.option - OR - | ||
19 | - %div | ||
20 | - = w.label :email | 22 | + %div.email{:class => w.object.email.present? ? 'choosen' : nil} |
21 | = w.text_field :email | 23 | = w.text_field :email |
22 | \ No newline at end of file | 24 | \ No newline at end of file |
public/javascripts/form.js
1 | $(function(){ | 1 | $(function(){ |
2 | activateNestedForms(); | 2 | activateNestedForms(); |
3 | + | ||
4 | + if($('div.watcher.nested').length) | ||
5 | + activateWatcherTypeSelector(); | ||
3 | }); | 6 | }); |
4 | 7 | ||
5 | function activateNestedForms() { | 8 | function activateNestedForms() { |
@@ -33,7 +36,8 @@ function appendNestedItem() { | @@ -33,7 +36,8 @@ function appendNestedItem() { | ||
33 | timestamp = timestamp.valueOf(); | 36 | timestamp = timestamp.valueOf(); |
34 | input.attr('id', input.attr('id').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2')); | 37 | input.attr('id', input.attr('id').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2')); |
35 | input.attr('name', input.attr('name').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2')); | 38 | input.attr('name', input.attr('name').replace(/([_\[])\d+([\]_])/,'$1'+timestamp+'$2')); |
36 | - input.val(''); | 39 | + if(input.attr('type') != 'radio') |
40 | + input.val(''); | ||
37 | }); | 41 | }); |
38 | addLink.before(nestedItem); | 42 | addLink.before(nestedItem); |
39 | } | 43 | } |
@@ -49,4 +53,13 @@ function removeNestedItem() { | @@ -49,4 +53,13 @@ function removeNestedItem() { | ||
49 | $("input[name='"+idFieldName+"']").after(destroyFlag); | 53 | $("input[name='"+idFieldName+"']").after(destroyFlag); |
50 | } | 54 | } |
51 | nestedItem.hide(); | 55 | nestedItem.hide(); |
56 | +} | ||
57 | + | ||
58 | +function activateWatcherTypeSelector() { | ||
59 | + $('div.watcher input[name*=watcher_type]').live('click', function(){ | ||
60 | + var choosen = $(this).val(); | ||
61 | + var wrapper = $(this).closest('.nested'); | ||
62 | + wrapper.find('div.choosen').removeClass('choosen'); | ||
63 | + wrapper.find('div.'+choosen).addClass('choosen'); | ||
64 | + }); | ||
52 | } | 65 | } |
53 | \ No newline at end of file | 66 | \ No newline at end of file |
public/stylesheets/application.css
@@ -486,6 +486,18 @@ a.button.active { | @@ -486,6 +486,18 @@ a.button.active { | ||
486 | margin-right: 14px; | 486 | margin-right: 14px; |
487 | } | 487 | } |
488 | 488 | ||
489 | +/* Watchers Form */ | ||
490 | +div.nested.watcher .user, div.nested.watcher .email { | ||
491 | + display: none; | ||
492 | +} | ||
493 | +div.nested.watcher .choosen { | ||
494 | + display: block; | ||
495 | +} | ||
496 | +div.nested.watcher .choose { | ||
497 | + margin-bottom: 0.5em; | ||
498 | +} | ||
499 | + | ||
500 | + | ||
489 | /* Apps Table */ | 501 | /* Apps Table */ |
490 | table.apps tbody tr:hover td ,table.errs tbody tr:hover td { background-color: #F2F2F2;} | 502 | table.apps tbody tr:hover td ,table.errs tbody tr:hover td { background-color: #F2F2F2;} |
491 | 503 |